diff --git a/ASCOM.MeadeAutostar497.Telescope.Validation.txt b/ASCOM.MeadeAutostar497.Telescope.Validation.txt
new file mode 100644
index 0000000..eff5811
--- /dev/null
+++ b/ASCOM.MeadeAutostar497.Telescope.Validation.txt
@@ -0,0 +1,268 @@
+Conform Report Hash (V1): 671D83C15427DD14D9FA7F5A6C62D6B21372362C5173A2B95171D14D7442358DCF3950481797D63EB94E642D2563C3094C387C23D65466833FEA5E64CD045B46
+
+
+ConformanceCheck ASCOM Device Conformance Checker Version 6.4.63.0, Build time: 18/12/2018 08:58:34
+ConformanceCheck Running on: ASCOM Platform 6.4 SP1 6.4.1.2695
+
+ConformanceCheck Driver ProgID: ASCOM.MeadeAutostar497.Telescope
+
+Error handling
+Error number for "Not Implemented" is: 80040400
+Error number for "Invalid Value 1" is: 80040401
+Error number for "Invalid Value 2" is: 80040405
+Error number for "Value Not Set 1" is: 80040402
+Error number for "Value Not Set 2" is: 80040403
+Error messages will not be interpreted to infer state.
+
+18:07:45.625 Driver Access Checks OK
+18:07:46.272 AccessChecks OK Successfully created driver using late binding
+18:07:46.685 AccessChecks OK Successfully connected using late binding
+18:07:46.689 AccessChecks INFO The driver is a .NET object
+18:07:46.693 AccessChecks INFO The AssemblyQualifiedName is: ASCOM.MeadeAutostar497.Telescope, ASCOM.MeadeAutostar497.Telescope, Version=
+18:07:46.697 AccessChecks INFO The driver implements interface: ASCOM.DeviceInterface.ITelescopeV3
+18:07:46.701 AccessChecks INFO The driver implements interface: ASCOM.DeviceInterface.IFocuserV3
+18:07:47.416 AccessChecks INFO Device does not expose interface ITelescopeV2
+18:07:48.387 AccessChecks INFO Device exposes interface ITelescopeV3
+18:07:49.708 AccessChecks OK Successfully created driver using driver access toolkit
+18:07:50.029 AccessChecks OK Successfully connected using driver access toolkit
+
+Conform is using ASCOM.DriverAccess.Telescope to get a Telescope object
+18:07:51.351 ConformanceCheck OK Driver instance created successfully
+18:07:51.775 ConformanceCheck OK Connected OK
+
+Common Driver Methods
+18:07:51.817 InterfaceVersion OK 3
+18:07:51.845 Connected OK True
+18:07:51.874 Description OK Meade Autostar 497 .net
+18:07:51.903 DriverInfo OK Information about the driver itself. Version: 0.0
+18:07:51.932 DriverVersion OK 0.0
+18:07:51.961 Name OK Meade Autostar 497 .net
+18:07:51.990 CommandString INFO Conform cannot test the CommandString method
+18:07:51.996 CommandBlind INFO Conform cannot test the CommandBlind method
+18:07:52.002 CommandBool INFO Conform cannot test the CommandBool method
+18:07:52.008 Action INFO Conform cannot test the Action method
+18:07:52.015 SupportedActions OK Driver returned an empty action list
+
+Can Properties
+18:07:52.082 CanFindHome OK False
+18:07:52.089 CanPark OK True
+18:07:52.096 CanPulseGuide OK True
+18:07:52.102 CanSetDeclinationRate OK False
+18:07:52.109 CanSetGuideRates OK False
+18:07:52.117 CanSetPark OK False
+18:07:52.125 CanSetPierSide OK False
+18:07:52.177 CanSetRightAscensionRate OK False
+18:07:52.185 CanSetTracking OK False
+18:07:52.193 CanSlew OK True
+18:07:52.200 CanSlewltAz OK True
+18:07:52.208 CanSlewAltAzAsync OK True
+18:07:52.216 CanSlewAsync OK True
+18:07:52.224 CanSync OK True
+18:07:52.231 CanSyncAltAz OK False
+18:07:52.239 CanUnPark OK False
+
+Pre-run Checks
+18:07:52.286 Mount Safety INFO Scope is not parked, continuing testing
+18:07:52.339 TimeCheck INFO PC Time Zone: GMT Summer Time, offset -1 hours.
+18:07:52.348 TimeCheck INFO PC UTCDate: 08-May-2019 17:07:52.347
+18:07:53.254 TimeCheck INFO Mount UTCDate: 02-May-2019 19:33:55.000
+
+Properties
+18:07:53.358 AlignmentMode OK algPolar
+18:07:53.515 Altitude OK 1.00
+18:07:53.555 ApertureArea OK Optional member threw a PropertyNotImplementedException exception.
+18:07:53.591 ApertureDiameter OK Optional member threw a PropertyNotImplementedException exception.
+18:07:53.622 AtHome OK False
+18:07:53.654 AtPark OK False
+18:07:53.847 Azimuth OK 45.67
+18:07:54.028 Declination OK -01:00:01.00
+18:07:54.060 DeclinationRate Read OK 0.00
+18:07:54.093 DeclinationRate Write OK CanSetDeclinationRate is False and a PropertyNotImplementedException exception was generated as expected
+18:07:54.126 DoesRefraction Read OK Optional member threw a PropertyNotImplementedException exception.
+18:07:54.159 DoesRefraction Write OK Optional member threw a PropertyNotImplementedException exception.
+18:07:54.193 EquatorialSystem OK equLocalTopocentric
+18:07:54.227 FocalLength OK Optional member threw a PropertyNotImplementedException exception.
+18:07:54.260 GuideRateDeclination Read OK Optional member threw a PropertyNotImplementedException exception.
+18:07:54.270 GuideRateDeclination Write OK CanSetGuideRates is False and a PropertyNotImplementedException exception was generated as expected
+18:07:54.303 GuideRateRightAscension Read OK Optional member threw a PropertyNotImplementedException exception.
+18:07:54.314 GuideRateRightAscension Write OK CanSetGuideRates is False and a PropertyNotImplementedException exception was generated as expected
+18:07:54.347 IsPulseGuiding OK False
+18:07:54.541 RightAscension OK 03:59:09.00
+18:07:54.575 RightAscensionRate Read OK 0.00
+18:07:54.609 RightAscensionRate Write OK CanSetRightAscensionRate is False and a PropertyNotImplementedException exception was generated as expected
+18:07:54.644 SiteElevation Read OK Optional member threw a PropertyNotImplementedException exception.
+18:07:54.678 SiteElevation Write OK Optional member threw a PropertyNotImplementedException exception.
+18:07:54.691 SiteElevation Write OK Optional member threw a PropertyNotImplementedException exception.
+18:07:54.703 SiteElevation Write OK Optional member threw a PropertyNotImplementedException exception.
+18:07:54.861 SiteLatitude Read OK 00:00:00.00
+18:07:54.900 SiteLatitude Write OK Invalid Value exception generated as expected on set site latitude < -90 degrees
+18:07:54.912 SiteLatitude Write OK Invalid Value exception generated as expected on set site latitude > 90 degrees
+18:07:55.315 SiteLatitude Write OK Legal value 00:00:00.00 degrees written successfully
+18:07:55.455 SiteLongitude Read OK -42:12:00.00
+18:07:55.490 SiteLongitude Write OK Invalid Value exception generated as expected on set site longitude < -180 degrees
+18:07:55.502 SiteLongitude Write OK Invalid Value exception generated as expected on set site longitude > 180 degrees
+18:07:56.090 SiteLongitude Write OK Legal value -42:12:00.00 degrees written successfully
+18:07:56.246 Slewing OK False
+18:07:56.280 SlewSettleTime Read OK Optional member threw a PropertyNotImplementedException exception.
+18:07:56.315 SlewSettleTime Write OK Optional member threw a PropertyNotImplementedException exception.
+18:07:56.328 SlewSettleTime Write OK Optional member threw a PropertyNotImplementedException exception.
+18:07:56.363 SideOfPier Read OK Optional member threw a PropertyNotImplementedException exception.
+18:07:56.578 SiderealTime OK 05:17:41.24
+18:07:56.590 SiderealTime INFO Scope and ASCOM sidereal times are up to 0.5 hour different, Scope: 05:17:41.24, ASCOM: 05:24:06.50
+18:07:56.626 TargetDeclination Read OK .NET Not InvalidOperationException generated on read before write
+18:07:56.661 TargetDeclination Write INFO Tests moved after the SlewToCoordinates tests so that Conform can check they properly set target coordinates.
+18:07:56.673 TargetRightAscension Read OK .NET Not InvalidOperationException generated on read before write
+18:07:56.708 TargetRightAscension Write INFO Tests moved after the SlewToCoordinates tests so that Conform can check they properly set target coordinates.
+18:07:56.720 Tracking Read OK True
+18:07:56.756 Tracking Write OK CanSetTracking is False and a PropertyNotImplementedException exception was generated as expected
+18:07:56.797 TrackingRates Found drive rate: driveSidereal
+18:07:56.809 TrackingRates OK Drive rates read OK
+18:07:56.822 TrackingRates OK Disposed tracking rates OK
+18:07:56.858 TrackingRates OK Successfully obtained a TrackingRates object after the previous TrackingRates object was disposed
+18:07:57.039 TrackingRate Read OK driveLunar
+18:07:57.075 TrackingRate Write OK Optional member threw a PropertyNotImplementedException exception.
+18:07:57.088 TrackingRate Write OK Optional member threw a PropertyNotImplementedException exception.
+18:07:57.624 UTCDate Read OK 02-May-2019 19:33:59.000
+18:07:58.626 UTCDate Write OK New UTCDate written successfully: 02/05/2019 20:33:59
+
+Methods
+18:07:59.997 CanMoveAxis:Primary OK CanMoveAxis:Primary True
+18:08:00.035 CanMoveAxis:Secondary OK CanMoveAxis:Secondary True
+18:08:00.072 CanMoveAxis:Tertiary OK CanMoveAxis:Tertiary False
+18:08:00.108 Park/Unpark INFO Tests skipped
+18:08:00.131 AbortSlew OK AbortSlew OK when not slewing
+18:08:00.199 AxisRate:Primary OK Axis rate minimum: 1 Axis rate maximum: 1
+18:08:00.211 AxisRate:Primary OK Axis rate minimum: 2 Axis rate maximum: 2
+18:08:00.225 AxisRate:Primary OK Axis rate minimum: 3 Axis rate maximum: 3
+18:08:00.239 AxisRate:Primary OK Axis rate minimum: 4 Axis rate maximum: 4
+18:08:00.253 AxisRate:Primary OK No overlapping axis rates found
+18:08:00.266 AxisRate:Primary OK No duplicate axis rates found
+18:08:00.279 AxisRate:Primary OK Successfully disposed of rate 1 - 1
+18:08:00.295 AxisRate:Primary OK Successfully disposed of rate 2 - 2
+18:08:00.310 AxisRate:Primary OK Successfully disposed of rate 3 - 3
+18:08:00.322 AxisRate:Primary OK Successfully disposed of rate 4 - 4
+18:08:00.336 AxisRate:Primary OK Disposed axis rates OK
+18:08:00.350 AxisRate:Secondary OK Axis rate minimum: 1 Axis rate maximum: 1
+18:08:00.362 AxisRate:Secondary OK Axis rate minimum: 2 Axis rate maximum: 2
+18:08:00.375 AxisRate:Secondary OK Axis rate minimum: 3 Axis rate maximum: 3
+18:08:00.387 AxisRate:Secondary OK Axis rate minimum: 4 Axis rate maximum: 4
+18:08:00.400 AxisRate:Secondary OK No overlapping axis rates found
+18:08:00.414 AxisRate:Secondary OK No duplicate axis rates found
+18:08:00.445 AxisRate:Secondary OK Successfully disposed of rate 1 - 1
+18:08:00.458 AxisRate:Secondary OK Successfully disposed of rate 2 - 2
+18:08:00.472 AxisRate:Secondary OK Successfully disposed of rate 3 - 3
+18:08:00.487 AxisRate:Secondary OK Successfully disposed of rate 4 - 4
+18:08:00.501 AxisRate:Secondary OK Disposed axis rates OK
+18:08:00.517 AxisRate:Tertiary OK Empty axis rate returned
+18:08:00.531 AxisRate:Tertiary OK Disposed axis rates OK
+18:08:00.550 FindHome OK CanFindHome is False and a MethodNotImplementedException exception was generated as expected
+18:08:00.606 MoveAxis Primary OK Can successfully set a movement rate of zero
+18:08:00.622 MoveAxis Primary OK Exception correctly generated when move axis is set below lowest rate (0.5)
+18:08:00.659 MoveAxis Primary OK Exception correctly generated when move axis is set above highest rate (5)
+18:08:04.867 MoveAxis Primary OK Successfully moved axis at minimum rate: 1
+18:08:09.770 MoveAxis Primary OK Successfully moved axis at maximum rate: 4
+18:08:13.981 MoveAxis Primary OK Tracking state correctly restored after MoveAxis when CanSetTracking is false
+18:08:13.998 MoveAxis Primary OK AxisRates object successfully disposed
+18:08:14.057 MoveAxis Secondary OK Can successfully set a movement rate of zero
+18:08:14.072 MoveAxis Secondary OK Exception correctly generated when move axis is set below lowest rate (0.5)
+18:08:14.107 MoveAxis Secondary OK Exception correctly generated when move axis is set above highest rate (5)
+18:08:18.317 MoveAxis Secondary OK Successfully moved axis at minimum rate: 1
+18:08:23.262 MoveAxis Secondary OK Successfully moved axis at maximum rate: 4
+18:08:27.473 MoveAxis Secondary OK Tracking state correctly restored after MoveAxis when CanSetTracking is false
+18:08:27.492 MoveAxis Secondary OK AxisRates object successfully disposed
+18:08:27.551 MoveAxis Tertiary OK CanMoveAxis Tertiary is False and a MethodNotImplementedException exception was generated as expected
+18:08:29.592 PulseGuide OK Synchronous pulse guide found OK
+18:08:54.449 SlewToCoordinates INFO Slewed within 39.2 arc seconds of expected RA: 04:18:14.61, actual RA: 04:18:12.00
+18:08:54.463 SlewToCoordinates INFO Slewed within 7199.0 arc seconds of expected DEC: 01:00:00.00, actual DEC: -00:59:59.00
+18:08:54.478 SlewToCoordinates OK The TargetRightAscension property 04:18:14.61 matches the expected RA OK.
+18:08:54.492 SlewToCoordinates OK The TargetDeclination property 01:00:00.00 matches the expected Declination OK.
+18:08:54.548 SlewToCoordinates (Bad L) OK Correctly rejected bad RA coordinate: -01:00:00.00
+18:08:55.301 SlewToCoordinates (Bad L) OK Correctly rejected bad Dec coordinate: -100:00:00.00
+18:08:55.360 SlewToCoordinates (Bad H) OK Correctly rejected bad RA coordinate: 25:00:00.00
+18:08:56.199 SlewToCoordinates (Bad H) OK Correctly rejected bad Dec coordinate: 100:00:00.00
+18:09:20.477 SlewToCoordinatesAsync INFO Slewed within 19.3 arc seconds of expected RA: 03:18:41.28, actual RA: 03:18:40.00
+18:09:20.490 SlewToCoordinatesAsync INFO Slewed within 14398.0 arc seconds of expected DEC: 02:00:00.00, actual DEC: -01:59:58.00
+18:09:20.503 SlewToCoordinatesAsync OK The TargetRightAscension property 03:18:41.28 matches the expected RA OK.
+18:09:20.516 SlewToCoordinatesAsync OK The TargetDeclination property 02:00:00.00 matches the expected Declination OK.
+18:09:20.558 SlewToCoordinatesAsync (Bad L) OK Correctly rejected bad RA coordinate: -01:00:00.00
+18:09:21.381 SlewToCoordinatesAsync (Bad L) OK Correctly rejected bad Dec coordinate: -100:00:00.00
+18:09:21.442 SlewToCoordinatesAsync (Bad H) OK Correctly rejected bad RA coordinate: 25:00:00.00
+18:09:22.292 SlewToCoordinatesAsync (Bad H) OK Correctly rejected bad Dec coordinate: 100:00:00.00
+18:09:44.520 SyncToCoordinates INFO Slewed to start position within 56.8 arc seconds of expected RA: 02:19:07.79, actual RA: 02:19:04.00
+18:09:44.534 SyncToCoordinates OK Slewed to start position OK. DEC: 00:00:00.00
+18:09:47.045 SyncToCoordinates INFO Synced to sync position within 71.8 arc seconds of expected RA: 02:15:07.79, actual RA: 02:15:03.00
+18:09:47.058 SyncToCoordinates INFO Synced to sync position within 3660.0 arc seconds of expected DEC: -01:00:00.00, actual DEC: 00:01:00.00
+18:09:47.071 SyncToCoordinates OK The TargetRightAscension property 02:15:07.79 matches the expected RA OK.
+18:09:47.085 SyncToCoordinates OK The TargetDeclination property -01:00:00.00 matches the expected Declination OK.
+18:10:08.444 SyncToCoordinates INFO Slewed back to start position within 56.8 arc seconds of expected RA: 02:19:07.79, actual RA: 02:19:04.00
+18:10:08.458 SyncToCoordinates OK Slewed back to start position OK. DEC: 00:00:00.00
+18:10:10.791 SyncToCoordinates INFO Synced to reversed sync position within 71.8 arc seconds of expected RA: 02:23:07.79, actual RA: 02:23:03.00
+18:10:10.806 SyncToCoordinates INFO Synced to reversed sync position within 7200.0 arc seconds of expected DEC: 01:00:00.00, actual DEC: -01:00:00.00
+18:10:32.484 SyncToCoordinates INFO Slewed back to start position within 56.8 arc seconds of expected RA: 02:19:07.79, actual RA: 02:19:04.00
+18:10:32.498 SyncToCoordinates OK Slewed back to start position OK. DEC: 00:00:00.00
+18:10:32.537 SyncToCoordinates (Bad L) OK Correctly rejected bad RA coordinate: -01:00:00.00
+18:10:33.329 SyncToCoordinates (Bad L) OK Correctly rejected bad Dec coordinate: -100:00:00.00
+18:10:33.389 SyncToCoordinates (Bad H) OK Correctly rejected bad RA coordinate: 25:00:00.00
+18:10:34.242 SyncToCoordinates (Bad H) OK Correctly rejected bad Dec coordinate: 100:00:00.00
+18:10:34.301 TargetRightAscension Write OK Invalid Value exception generated as expected on set TargetRightAscension < 0 hours
+18:10:34.315 TargetRightAscension Write OK Invalid Value exception generated as expected on set TargetRightAscension > 24 hours
+18:10:34.979 TargetRightAscension Write OK Legal value 01:20:19.62 HH:MM:SS written successfully
+18:10:35.016 TargetDeclination Write OK Invalid Value exception generated as expected on set TargetDeclination < -90 degrees
+18:10:35.032 TargetDeclination Write OK Invalid Value exception generated as expected on set TargetDeclination < -90 degrees
+18:10:35.652 TargetDeclination Write OK Legal value 01:00:00.00 DD:MM:SS written successfully
+18:10:56.417 SlewToTarget INFO Slewed within 14.8 arc seconds of expected RA: 02:20:20.99, actual RA: 02:20:20.00
+18:10:56.434 SlewToTarget INFO Slewed within 21596.0 arc seconds of expected DEC: 03:00:00.00, actual DEC: -02:59:56.00
+18:10:56.449 SlewToTarget OK The TargetRightAscension property 02:20:20.99 matches the expected RA OK.
+18:10:56.463 SlewToTarget OK The TargetDeclination property 03:00:00.00 matches the expected Declination OK.
+18:10:56.504 SlewToTarget (Bad L) OK Telescope.TargetRA correctly rejected bad RA coordinate: -01:00:00.00
+18:10:56.676 SlewToTarget (Bad L) OK Telescope.TargetDeclination correctly rejected bad Dec coordinate: -100:00:00.00
+18:10:56.736 SlewToTarget (Bad H) OK Telescope.TargetRA correctly rejected bad RA coordinate: 25:00:00.00
+18:10:56.915 SlewToTarget (Bad H) OK Telescope.TargetDeclination correctly rejected bad Dec coordinate: 100:00:00.00
+18:11:20.512 SlewToTargetAsync INFO Slewed within 35.1 arc seconds of expected RA: 01:20:42.34, actual RA: 01:20:40.00
+18:11:20.526 SlewToTargetAsync INFO Slewed within 28797.0 arc seconds of expected DEC: 04:00:00.00, actual DEC: -03:59:57.00
+18:11:20.539 SlewToTargetAsync OK The TargetRightAscension property 01:20:42.34 matches the expected RA OK.
+18:11:20.553 SlewToTargetAsync OK The TargetDeclination property 04:00:00.00 matches the expected Declination OK.
+18:11:20.593 SlewToTargetAsync (Bad L) OK Telescope.TargetRA correctly rejected bad RA coordinate: -01:00:00.00
+18:11:20.774 SlewToTargetAsync (Bad L) OK Telescope.TargetDeclination correctly rejected bad Dec coordinate: -100:00:00.00
+18:11:20.833 SlewToTargetAsync (Bad H) OK Telescope.TargetRA correctly rejected bad RA coordinate: 25:00:00.00
+18:11:21.032 SlewToTargetAsync (Bad H) OK Telescope.TargetDeclination correctly rejected bad Dec coordinate: 100:00:00.00
+18:11:21.091 DestinationSideOfPier Test skipped as AligmentMode is not German Polar
+18:11:22.864 SlewToAltAz INFO Slewed to within 144:49:47.00 DD:MM:SS of expected Azimuth: 150:00:00.00
+18:11:22.880 SlewToAltAz INFO Slewed to within 46:00:01.00 DD:MM:SS of expected Altitude: 50:00:00.00
+18:11:22.920 SlewToAltAz (Bad L) OK Correctly rejected bad Altitude coordinate: -100:00:00.00
+18:11:23.710 SlewToAltAz (Bad L) OK Correctly rejected bad Azimuth coordinate: -10:00:00.00
+18:11:23.771 SlewToAltAz (Bad H) OK Correctly rejected bad Altitude coordinate: 100:00:00.00
+18:11:24.447 SlewToAltAz (Bad H) OK Correctly rejected bad Azimuth coordinate: 370:00:00.00
+18:11:31.196 SlewToAltAzAsync INFO Slewed to within 149:51:53.00 DD:MM:SS of expected Azimuth: 155:00:00.00
+18:11:31.210 SlewToAltAzAsync INFO Slewed to within 51:00:01.00 DD:MM:SS of expected Altitude: 55:00:00.00
+18:11:31.251 SlewToAltAzAsync (Bad L) OK Correctly rejected bad Altitude coordinate: -100:00:00.00
+18:11:32.060 SlewToAltAzAsync (Bad L) OK Correctly rejected bad Azimuth coordinate: -10:00:00.00
+18:11:32.121 SlewToAltAzAsync (Bad H) OK Correctly rejected bad Altitude coordinate: 100:00:00.00
+18:11:32.814 SlewToAltAzAsync (Bad H) OK Correctly rejected bad Azimuth coordinate: 370:00:00.00
+18:11:56.494 SyncToTarget INFO Slewed to start position within 40.1 arc seconds of expected RA: 02:21:18.67, actual RA: 02:21:16.00
+18:11:56.509 SyncToTarget OK Slewed to start position OK. DEC: 00:00:00.00
+18:11:59.005 SyncToTarget INFO Synced to sync position within 55.1 arc seconds of expected RA: 02:17:18.67, actual RA: 02:17:15.00
+18:11:59.019 SyncToTarget INFO Synced to sync position within 3660.0 arc seconds of expected DEC: -01:00:00.00, actual DEC: 00:01:00.00
+18:12:22.398 SyncToTarget INFO Slewed back to start position within 40.1 arc seconds of expected RA: 02:21:18.67, actual RA: 02:21:16.00
+18:12:22.416 SyncToTarget OK Slewed back to start position OK. DEC: 00:00:00.00
+18:12:24.739 SyncToTarget INFO Synced to reversed sync position within 55.1 arc seconds of expected RA: 02:25:18.67, actual RA: 02:25:15.00
+18:12:24.754 SyncToTarget INFO Synced to reversed sync position within 7200.0 arc seconds of expected DEC: 01:00:00.00, actual DEC: -01:00:00.00
+18:12:46.438 SyncToTarget INFO Slewed back to start position within 40.1 arc seconds of expected RA: 02:21:18.67, actual RA: 02:21:16.00
+18:12:46.452 SyncToTarget OK Slewed back to start position OK. DEC: 00:00:00.00
+18:12:46.491 SyncToTarget (Bad L) OK Telescope.TargetRA correctly rejected bad RA coordinate: -01:00:00.00
+18:12:46.643 SyncToTarget (Bad L) OK Telescope.TargetDeclination correctly rejected bad Dec coordinate: -100:00:00.00
+18:12:46.702 SyncToTarget (Bad H) OK Telescope.TargetRA correctly rejected bad RA coordinate: 25:00:00.00
+18:12:46.884 SyncToTarget (Bad H) OK Telescope.TargetDeclination correctly rejected bad Dec coordinate: 100:00:00.00
+18:12:47.702 SyncToAltAz OK CanSyncAltAz is False and a MethodNotImplementedException exception was generated as expected
+
+SideOfPier Model Tests
+18:12:47.769 SideOfPier Model Tests INFO Tests skipped because this driver does Not support SideOfPier Read
+
+Post-run Checks
+18:12:47.862 Mount Safety INFO Tracking can't be turned off for this mount, please switch off manually.
+
+Conformance test complete
+
+No errors, warnings or issues found: your driver passes ASCOM validation!!
+
+Driver Hash Value: 0C55C8535B9B3A4048581454F9D6A263EFD16E20AEC783762006739F671F586B64F1D8DD3E1E613C27A5B24838AEB8656C2A19BD1EE69177ECF2619599C0DA3C
diff --git a/ConformanceResult.txt b/ConformanceResult.txt
new file mode 100644
index 0000000..beecf54
--- /dev/null
+++ b/ConformanceResult.txt
@@ -0,0 +1,272 @@
+Start-up ASCOM Device Conformance Checker - 64bit mode
+Start-up ASCOM Platform 6.4 SP1 6.4.1.2695
+
+
+ConformanceCheck ASCOM Device Conformance Checker Version 6.4.63.0, Build time: 18/12/2018 08:58:34
+ConformanceCheck Running on: ASCOM Platform 6.4 SP1 6.4.1.2695
+
+ConformanceCheck Driver ProgID: ASCOM.MeadeAutostar497.Telescope
+
+Error handling
+Error number for "Not Implemented" is: 80040400
+Error number for "Invalid Value 1" is: 80040401
+Error number for "Invalid Value 2" is: 80040405
+Error number for "Value Not Set 1" is: 80040402
+Error number for "Value Not Set 2" is: 80040403
+Error messages will not be interpreted to infer state.
+
+18:07:45.625 Driver Access Checks OK
+18:07:46.272 AccessChecks OK Successfully created driver using late binding
+18:07:46.685 AccessChecks OK Successfully connected using late binding
+18:07:46.689 AccessChecks INFO The driver is a .NET object
+18:07:46.693 AccessChecks INFO The AssemblyQualifiedName is: ASCOM.MeadeAutostar497.Telescope, ASCOM.MeadeAutostar497.Telescope, Version=
+18:07:46.697 AccessChecks INFO The driver implements interface: ASCOM.DeviceInterface.ITelescopeV3
+18:07:46.701 AccessChecks INFO The driver implements interface: ASCOM.DeviceInterface.IFocuserV3
+18:07:47.416 AccessChecks INFO Device does not expose interface ITelescopeV2
+18:07:48.387 AccessChecks INFO Device exposes interface ITelescopeV3
+18:07:49.708 AccessChecks OK Successfully created driver using driver access toolkit
+18:07:50.029 AccessChecks OK Successfully connected using driver access toolkit
+
+Conform is using ASCOM.DriverAccess.Telescope to get a Telescope object
+18:07:51.351 ConformanceCheck OK Driver instance created successfully
+18:07:51.775 ConformanceCheck OK Connected OK
+
+Common Driver Methods
+18:07:51.817 InterfaceVersion OK 3
+18:07:51.845 Connected OK True
+18:07:51.874 Description OK Meade Autostar 497 .net
+18:07:51.903 DriverInfo OK Information about the driver itself. Version: 0.0
+18:07:51.932 DriverVersion OK 0.0
+18:07:51.961 Name OK Meade Autostar 497 .net
+18:07:51.990 CommandString INFO Conform cannot test the CommandString method
+18:07:51.996 CommandBlind INFO Conform cannot test the CommandBlind method
+18:07:52.002 CommandBool INFO Conform cannot test the CommandBool method
+18:07:52.008 Action INFO Conform cannot test the Action method
+18:07:52.015 SupportedActions OK Driver returned an empty action list
+
+Can Properties
+18:07:52.082 CanFindHome OK False
+18:07:52.089 CanPark OK True
+18:07:52.096 CanPulseGuide OK True
+18:07:52.102 CanSetDeclinationRate OK False
+18:07:52.109 CanSetGuideRates OK False
+18:07:52.117 CanSetPark OK False
+18:07:52.125 CanSetPierSide OK False
+18:07:52.177 CanSetRightAscensionRate OK False
+18:07:52.185 CanSetTracking OK False
+18:07:52.193 CanSlew OK True
+18:07:52.200 CanSlewltAz OK True
+18:07:52.208 CanSlewAltAzAsync OK True
+18:07:52.216 CanSlewAsync OK True
+18:07:52.224 CanSync OK True
+18:07:52.231 CanSyncAltAz OK False
+18:07:52.239 CanUnPark OK False
+
+Pre-run Checks
+18:07:52.286 Mount Safety INFO Scope is not parked, continuing testing
+18:07:52.339 TimeCheck INFO PC Time Zone: GMT Summer Time, offset -1 hours.
+18:07:52.348 TimeCheck INFO PC UTCDate: 08-May-2019 17:07:52.347
+18:07:53.254 TimeCheck INFO Mount UTCDate: 02-May-2019 19:33:55.000
+
+Properties
+18:07:53.358 AlignmentMode OK algPolar
+18:07:53.515 Altitude OK 1.00
+18:07:53.555 ApertureArea OK Optional member threw a PropertyNotImplementedException exception.
+18:07:53.591 ApertureDiameter OK Optional member threw a PropertyNotImplementedException exception.
+18:07:53.622 AtHome OK False
+18:07:53.654 AtPark OK False
+18:07:53.847 Azimuth OK 45.67
+18:07:54.028 Declination OK -01:00:01.00
+18:07:54.060 DeclinationRate Read OK 0.00
+18:07:54.093 DeclinationRate Write OK CanSetDeclinationRate is False and a PropertyNotImplementedException exception was generated as expected
+18:07:54.126 DoesRefraction Read OK Optional member threw a PropertyNotImplementedException exception.
+18:07:54.159 DoesRefraction Write OK Optional member threw a PropertyNotImplementedException exception.
+18:07:54.193 EquatorialSystem OK equLocalTopocentric
+18:07:54.227 FocalLength OK Optional member threw a PropertyNotImplementedException exception.
+18:07:54.260 GuideRateDeclination Read OK Optional member threw a PropertyNotImplementedException exception.
+18:07:54.270 GuideRateDeclination Write OK CanSetGuideRates is False and a PropertyNotImplementedException exception was generated as expected
+18:07:54.303 GuideRateRightAscension Read OK Optional member threw a PropertyNotImplementedException exception.
+18:07:54.314 GuideRateRightAscension Write OK CanSetGuideRates is False and a PropertyNotImplementedException exception was generated as expected
+18:07:54.347 IsPulseGuiding OK False
+18:07:54.541 RightAscension OK 03:59:09.00
+18:07:54.575 RightAscensionRate Read OK 0.00
+18:07:54.609 RightAscensionRate Write OK CanSetRightAscensionRate is False and a PropertyNotImplementedException exception was generated as expected
+18:07:54.644 SiteElevation Read OK Optional member threw a PropertyNotImplementedException exception.
+18:07:54.678 SiteElevation Write OK Optional member threw a PropertyNotImplementedException exception.
+18:07:54.691 SiteElevation Write OK Optional member threw a PropertyNotImplementedException exception.
+18:07:54.703 SiteElevation Write OK Optional member threw a PropertyNotImplementedException exception.
+18:07:54.861 SiteLatitude Read OK 00:00:00.00
+18:07:54.900 SiteLatitude Write OK Invalid Value exception generated as expected on set site latitude < -90 degrees
+18:07:54.912 SiteLatitude Write OK Invalid Value exception generated as expected on set site latitude > 90 degrees
+18:07:55.315 SiteLatitude Write OK Legal value 00:00:00.00 degrees written successfully
+18:07:55.455 SiteLongitude Read OK -42:12:00.00
+18:07:55.490 SiteLongitude Write OK Invalid Value exception generated as expected on set site longitude < -180 degrees
+18:07:55.502 SiteLongitude Write OK Invalid Value exception generated as expected on set site longitude > 180 degrees
+18:07:56.090 SiteLongitude Write OK Legal value -42:12:00.00 degrees written successfully
+18:07:56.246 Slewing OK False
+18:07:56.280 SlewSettleTime Read OK Optional member threw a PropertyNotImplementedException exception.
+18:07:56.315 SlewSettleTime Write OK Optional member threw a PropertyNotImplementedException exception.
+18:07:56.328 SlewSettleTime Write OK Optional member threw a PropertyNotImplementedException exception.
+18:07:56.363 SideOfPier Read OK Optional member threw a PropertyNotImplementedException exception.
+18:07:56.578 SiderealTime OK 05:17:41.24
+18:07:56.590 SiderealTime INFO Scope and ASCOM sidereal times are up to 0.5 hour different, Scope: 05:17:41.24, ASCOM: 05:24:06.50
+18:07:56.626 TargetDeclination Read OK .NET Not InvalidOperationException generated on read before write
+18:07:56.661 TargetDeclination Write INFO Tests moved after the SlewToCoordinates tests so that Conform can check they properly set target coordinates.
+18:07:56.673 TargetRightAscension Read OK .NET Not InvalidOperationException generated on read before write
+18:07:56.708 TargetRightAscension Write INFO Tests moved after the SlewToCoordinates tests so that Conform can check they properly set target coordinates.
+18:07:56.720 Tracking Read OK True
+18:07:56.756 Tracking Write OK CanSetTracking is False and a PropertyNotImplementedException exception was generated as expected
+18:07:56.797 TrackingRates Found drive rate: driveSidereal
+18:07:56.809 TrackingRates OK Drive rates read OK
+18:07:56.822 TrackingRates OK Disposed tracking rates OK
+18:07:56.858 TrackingRates OK Successfully obtained a TrackingRates object after the previous TrackingRates object was disposed
+18:07:57.039 TrackingRate Read OK driveLunar
+18:07:57.075 TrackingRate Write OK Optional member threw a PropertyNotImplementedException exception.
+18:07:57.088 TrackingRate Write OK Optional member threw a PropertyNotImplementedException exception.
+18:07:57.624 UTCDate Read OK 02-May-2019 19:33:59.000
+18:07:58.626 UTCDate Write OK New UTCDate written successfully: 02/05/2019 20:33:59
+
+Methods
+18:07:59.997 CanMoveAxis:Primary OK CanMoveAxis:Primary True
+18:08:00.035 CanMoveAxis:Secondary OK CanMoveAxis:Secondary True
+18:08:00.072 CanMoveAxis:Tertiary OK CanMoveAxis:Tertiary False
+18:08:00.108 Park/Unpark INFO Tests skipped
+18:08:00.131 AbortSlew OK AbortSlew OK when not slewing
+18:08:00.199 AxisRate:Primary OK Axis rate minimum: 1 Axis rate maximum: 1
+18:08:00.211 AxisRate:Primary OK Axis rate minimum: 2 Axis rate maximum: 2
+18:08:00.225 AxisRate:Primary OK Axis rate minimum: 3 Axis rate maximum: 3
+18:08:00.239 AxisRate:Primary OK Axis rate minimum: 4 Axis rate maximum: 4
+18:08:00.253 AxisRate:Primary OK No overlapping axis rates found
+18:08:00.266 AxisRate:Primary OK No duplicate axis rates found
+18:08:00.279 AxisRate:Primary OK Successfully disposed of rate 1 - 1
+18:08:00.295 AxisRate:Primary OK Successfully disposed of rate 2 - 2
+18:08:00.310 AxisRate:Primary OK Successfully disposed of rate 3 - 3
+18:08:00.322 AxisRate:Primary OK Successfully disposed of rate 4 - 4
+18:08:00.336 AxisRate:Primary OK Disposed axis rates OK
+18:08:00.350 AxisRate:Secondary OK Axis rate minimum: 1 Axis rate maximum: 1
+18:08:00.362 AxisRate:Secondary OK Axis rate minimum: 2 Axis rate maximum: 2
+18:08:00.375 AxisRate:Secondary OK Axis rate minimum: 3 Axis rate maximum: 3
+18:08:00.387 AxisRate:Secondary OK Axis rate minimum: 4 Axis rate maximum: 4
+18:08:00.400 AxisRate:Secondary OK No overlapping axis rates found
+18:08:00.414 AxisRate:Secondary OK No duplicate axis rates found
+18:08:00.445 AxisRate:Secondary OK Successfully disposed of rate 1 - 1
+18:08:00.458 AxisRate:Secondary OK Successfully disposed of rate 2 - 2
+18:08:00.472 AxisRate:Secondary OK Successfully disposed of rate 3 - 3
+18:08:00.487 AxisRate:Secondary OK Successfully disposed of rate 4 - 4
+18:08:00.501 AxisRate:Secondary OK Disposed axis rates OK
+18:08:00.517 AxisRate:Tertiary OK Empty axis rate returned
+18:08:00.531 AxisRate:Tertiary OK Disposed axis rates OK
+18:08:00.550 FindHome OK CanFindHome is False and a MethodNotImplementedException exception was generated as expected
+18:08:00.606 MoveAxis Primary OK Can successfully set a movement rate of zero
+18:08:00.622 MoveAxis Primary OK Exception correctly generated when move axis is set below lowest rate (0.5)
+18:08:00.659 MoveAxis Primary OK Exception correctly generated when move axis is set above highest rate (5)
+18:08:04.867 MoveAxis Primary OK Successfully moved axis at minimum rate: 1
+18:08:09.770 MoveAxis Primary OK Successfully moved axis at maximum rate: 4
+18:08:13.981 MoveAxis Primary OK Tracking state correctly restored after MoveAxis when CanSetTracking is false
+18:08:13.998 MoveAxis Primary OK AxisRates object successfully disposed
+18:08:14.057 MoveAxis Secondary OK Can successfully set a movement rate of zero
+18:08:14.072 MoveAxis Secondary OK Exception correctly generated when move axis is set below lowest rate (0.5)
+18:08:14.107 MoveAxis Secondary OK Exception correctly generated when move axis is set above highest rate (5)
+18:08:18.317 MoveAxis Secondary OK Successfully moved axis at minimum rate: 1
+18:08:23.262 MoveAxis Secondary OK Successfully moved axis at maximum rate: 4
+18:08:27.473 MoveAxis Secondary OK Tracking state correctly restored after MoveAxis when CanSetTracking is false
+18:08:27.492 MoveAxis Secondary OK AxisRates object successfully disposed
+18:08:27.551 MoveAxis Tertiary OK CanMoveAxis Tertiary is False and a MethodNotImplementedException exception was generated as expected
+18:08:29.592 PulseGuide OK Synchronous pulse guide found OK
+18:08:54.449 SlewToCoordinates INFO Slewed within 39.2 arc seconds of expected RA: 04:18:14.61, actual RA: 04:18:12.00
+18:08:54.463 SlewToCoordinates INFO Slewed within 7199.0 arc seconds of expected DEC: 01:00:00.00, actual DEC: -00:59:59.00
+18:08:54.478 SlewToCoordinates OK The TargetRightAscension property 04:18:14.61 matches the expected RA OK.
+18:08:54.492 SlewToCoordinates OK The TargetDeclination property 01:00:00.00 matches the expected Declination OK.
+18:08:54.548 SlewToCoordinates (Bad L) OK Correctly rejected bad RA coordinate: -01:00:00.00
+18:08:55.301 SlewToCoordinates (Bad L) OK Correctly rejected bad Dec coordinate: -100:00:00.00
+18:08:55.360 SlewToCoordinates (Bad H) OK Correctly rejected bad RA coordinate: 25:00:00.00
+18:08:56.199 SlewToCoordinates (Bad H) OK Correctly rejected bad Dec coordinate: 100:00:00.00
+18:09:20.477 SlewToCoordinatesAsync INFO Slewed within 19.3 arc seconds of expected RA: 03:18:41.28, actual RA: 03:18:40.00
+18:09:20.490 SlewToCoordinatesAsync INFO Slewed within 14398.0 arc seconds of expected DEC: 02:00:00.00, actual DEC: -01:59:58.00
+18:09:20.503 SlewToCoordinatesAsync OK The TargetRightAscension property 03:18:41.28 matches the expected RA OK.
+18:09:20.516 SlewToCoordinatesAsync OK The TargetDeclination property 02:00:00.00 matches the expected Declination OK.
+18:09:20.558 SlewToCoordinatesAsync (Bad L) OK Correctly rejected bad RA coordinate: -01:00:00.00
+18:09:21.381 SlewToCoordinatesAsync (Bad L) OK Correctly rejected bad Dec coordinate: -100:00:00.00
+18:09:21.442 SlewToCoordinatesAsync (Bad H) OK Correctly rejected bad RA coordinate: 25:00:00.00
+18:09:22.292 SlewToCoordinatesAsync (Bad H) OK Correctly rejected bad Dec coordinate: 100:00:00.00
+18:09:44.520 SyncToCoordinates INFO Slewed to start position within 56.8 arc seconds of expected RA: 02:19:07.79, actual RA: 02:19:04.00
+18:09:44.534 SyncToCoordinates OK Slewed to start position OK. DEC: 00:00:00.00
+18:09:47.045 SyncToCoordinates INFO Synced to sync position within 71.8 arc seconds of expected RA: 02:15:07.79, actual RA: 02:15:03.00
+18:09:47.058 SyncToCoordinates INFO Synced to sync position within 3660.0 arc seconds of expected DEC: -01:00:00.00, actual DEC: 00:01:00.00
+18:09:47.071 SyncToCoordinates OK The TargetRightAscension property 02:15:07.79 matches the expected RA OK.
+18:09:47.085 SyncToCoordinates OK The TargetDeclination property -01:00:00.00 matches the expected Declination OK.
+18:10:08.444 SyncToCoordinates INFO Slewed back to start position within 56.8 arc seconds of expected RA: 02:19:07.79, actual RA: 02:19:04.00
+18:10:08.458 SyncToCoordinates OK Slewed back to start position OK. DEC: 00:00:00.00
+18:10:10.791 SyncToCoordinates INFO Synced to reversed sync position within 71.8 arc seconds of expected RA: 02:23:07.79, actual RA: 02:23:03.00
+18:10:10.806 SyncToCoordinates INFO Synced to reversed sync position within 7200.0 arc seconds of expected DEC: 01:00:00.00, actual DEC: -01:00:00.00
+18:10:32.484 SyncToCoordinates INFO Slewed back to start position within 56.8 arc seconds of expected RA: 02:19:07.79, actual RA: 02:19:04.00
+18:10:32.498 SyncToCoordinates OK Slewed back to start position OK. DEC: 00:00:00.00
+18:10:32.537 SyncToCoordinates (Bad L) OK Correctly rejected bad RA coordinate: -01:00:00.00
+18:10:33.329 SyncToCoordinates (Bad L) OK Correctly rejected bad Dec coordinate: -100:00:00.00
+18:10:33.389 SyncToCoordinates (Bad H) OK Correctly rejected bad RA coordinate: 25:00:00.00
+18:10:34.242 SyncToCoordinates (Bad H) OK Correctly rejected bad Dec coordinate: 100:00:00.00
+18:10:34.301 TargetRightAscension Write OK Invalid Value exception generated as expected on set TargetRightAscension < 0 hours
+18:10:34.315 TargetRightAscension Write OK Invalid Value exception generated as expected on set TargetRightAscension > 24 hours
+18:10:34.979 TargetRightAscension Write OK Legal value 01:20:19.62 HH:MM:SS written successfully
+18:10:35.016 TargetDeclination Write OK Invalid Value exception generated as expected on set TargetDeclination < -90 degrees
+18:10:35.032 TargetDeclination Write OK Invalid Value exception generated as expected on set TargetDeclination < -90 degrees
+18:10:35.652 TargetDeclination Write OK Legal value 01:00:00.00 DD:MM:SS written successfully
+18:10:56.417 SlewToTarget INFO Slewed within 14.8 arc seconds of expected RA: 02:20:20.99, actual RA: 02:20:20.00
+18:10:56.434 SlewToTarget INFO Slewed within 21596.0 arc seconds of expected DEC: 03:00:00.00, actual DEC: -02:59:56.00
+18:10:56.449 SlewToTarget OK The TargetRightAscension property 02:20:20.99 matches the expected RA OK.
+18:10:56.463 SlewToTarget OK The TargetDeclination property 03:00:00.00 matches the expected Declination OK.
+18:10:56.504 SlewToTarget (Bad L) OK Telescope.TargetRA correctly rejected bad RA coordinate: -01:00:00.00
+18:10:56.676 SlewToTarget (Bad L) OK Telescope.TargetDeclination correctly rejected bad Dec coordinate: -100:00:00.00
+18:10:56.736 SlewToTarget (Bad H) OK Telescope.TargetRA correctly rejected bad RA coordinate: 25:00:00.00
+18:10:56.915 SlewToTarget (Bad H) OK Telescope.TargetDeclination correctly rejected bad Dec coordinate: 100:00:00.00
+18:11:20.512 SlewToTargetAsync INFO Slewed within 35.1 arc seconds of expected RA: 01:20:42.34, actual RA: 01:20:40.00
+18:11:20.526 SlewToTargetAsync INFO Slewed within 28797.0 arc seconds of expected DEC: 04:00:00.00, actual DEC: -03:59:57.00
+18:11:20.539 SlewToTargetAsync OK The TargetRightAscension property 01:20:42.34 matches the expected RA OK.
+18:11:20.553 SlewToTargetAsync OK The TargetDeclination property 04:00:00.00 matches the expected Declination OK.
+18:11:20.593 SlewToTargetAsync (Bad L) OK Telescope.TargetRA correctly rejected bad RA coordinate: -01:00:00.00
+18:11:20.774 SlewToTargetAsync (Bad L) OK Telescope.TargetDeclination correctly rejected bad Dec coordinate: -100:00:00.00
+18:11:20.833 SlewToTargetAsync (Bad H) OK Telescope.TargetRA correctly rejected bad RA coordinate: 25:00:00.00
+18:11:21.032 SlewToTargetAsync (Bad H) OK Telescope.TargetDeclination correctly rejected bad Dec coordinate: 100:00:00.00
+18:11:21.091 DestinationSideOfPier Test skipped as AligmentMode is not German Polar
+18:11:22.864 SlewToAltAz INFO Slewed to within 144:49:47.00 DD:MM:SS of expected Azimuth: 150:00:00.00
+18:11:22.880 SlewToAltAz INFO Slewed to within 46:00:01.00 DD:MM:SS of expected Altitude: 50:00:00.00
+18:11:22.920 SlewToAltAz (Bad L) OK Correctly rejected bad Altitude coordinate: -100:00:00.00
+18:11:23.710 SlewToAltAz (Bad L) OK Correctly rejected bad Azimuth coordinate: -10:00:00.00
+18:11:23.771 SlewToAltAz (Bad H) OK Correctly rejected bad Altitude coordinate: 100:00:00.00
+18:11:24.447 SlewToAltAz (Bad H) OK Correctly rejected bad Azimuth coordinate: 370:00:00.00
+18:11:31.196 SlewToAltAzAsync INFO Slewed to within 149:51:53.00 DD:MM:SS of expected Azimuth: 155:00:00.00
+18:11:31.210 SlewToAltAzAsync INFO Slewed to within 51:00:01.00 DD:MM:SS of expected Altitude: 55:00:00.00
+18:11:31.251 SlewToAltAzAsync (Bad L) OK Correctly rejected bad Altitude coordinate: -100:00:00.00
+18:11:32.060 SlewToAltAzAsync (Bad L) OK Correctly rejected bad Azimuth coordinate: -10:00:00.00
+18:11:32.121 SlewToAltAzAsync (Bad H) OK Correctly rejected bad Altitude coordinate: 100:00:00.00
+18:11:32.814 SlewToAltAzAsync (Bad H) OK Correctly rejected bad Azimuth coordinate: 370:00:00.00
+18:11:56.494 SyncToTarget INFO Slewed to start position within 40.1 arc seconds of expected RA: 02:21:18.67, actual RA: 02:21:16.00
+18:11:56.509 SyncToTarget OK Slewed to start position OK. DEC: 00:00:00.00
+18:11:59.005 SyncToTarget INFO Synced to sync position within 55.1 arc seconds of expected RA: 02:17:18.67, actual RA: 02:17:15.00
+18:11:59.019 SyncToTarget INFO Synced to sync position within 3660.0 arc seconds of expected DEC: -01:00:00.00, actual DEC: 00:01:00.00
+18:12:22.398 SyncToTarget INFO Slewed back to start position within 40.1 arc seconds of expected RA: 02:21:18.67, actual RA: 02:21:16.00
+18:12:22.416 SyncToTarget OK Slewed back to start position OK. DEC: 00:00:00.00
+18:12:24.739 SyncToTarget INFO Synced to reversed sync position within 55.1 arc seconds of expected RA: 02:25:18.67, actual RA: 02:25:15.00
+18:12:24.754 SyncToTarget INFO Synced to reversed sync position within 7200.0 arc seconds of expected DEC: 01:00:00.00, actual DEC: -01:00:00.00
+18:12:46.438 SyncToTarget INFO Slewed back to start position within 40.1 arc seconds of expected RA: 02:21:18.67, actual RA: 02:21:16.00
+18:12:46.452 SyncToTarget OK Slewed back to start position OK. DEC: 00:00:00.00
+18:12:46.491 SyncToTarget (Bad L) OK Telescope.TargetRA correctly rejected bad RA coordinate: -01:00:00.00
+18:12:46.643 SyncToTarget (Bad L) OK Telescope.TargetDeclination correctly rejected bad Dec coordinate: -100:00:00.00
+18:12:46.702 SyncToTarget (Bad H) OK Telescope.TargetRA correctly rejected bad RA coordinate: 25:00:00.00
+18:12:46.884 SyncToTarget (Bad H) OK Telescope.TargetDeclination correctly rejected bad Dec coordinate: 100:00:00.00
+18:12:47.702 SyncToAltAz OK CanSyncAltAz is False and a MethodNotImplementedException exception was generated as expected
+
+SideOfPier Model Tests
+18:12:47.769 SideOfPier Model Tests INFO Tests skipped because this driver does Not support SideOfPier Read
+
+Post-run Checks
+18:12:47.862 Mount Safety INFO Tracking can't be turned off for this mount, please switch off manually.
+
+Conformance test complete
+
+No errors, warnings or issues found: your driver passes ASCOM validation!!
+
+Driver Hash Value: 0C55C8535B9B3A4048581454F9D6A263EFD16E20AEC783762006739F671F586B64F1D8DD3E1E613C27A5B24838AEB8656C2A19BD1EE69177ECF2619599C0DA3C
+Report Hash Value: 671D83C15427DD14D9FA7F5A6C62D6B21372362C5173A2B95171D14D7442358DCF3950481797D63EB94E642D2563C3094C387C23D65466833FEA5E64CD045B46
+
+The validation file is: C:\Users\colin\Documents\ASCOM\Logs 2019-05-08\ASCOM.MeadeAutostar497.Telescope.Validation.txt
diff --git a/MeadeAutostar497.UnitTests/BootstrapAscomProfileStore.ps1 b/MeadeAutostar497.UnitTests/BootstrapAscomProfileStore.ps1
new file mode 100644
index 0000000..213c64d
--- /dev/null
+++ b/MeadeAutostar497.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/MeadeAutostar497.UnitTests/MeadeAutostar497.UnitTests.csproj b/MeadeAutostar497.UnitTests/MeadeAutostar497.UnitTests.csproj
new file mode 100644
index 0000000..a7a4fae
--- /dev/null
+++ b/MeadeAutostar497.UnitTests/MeadeAutostar497.UnitTests.csproj
@@ -0,0 +1,126 @@
+
+
+
+
+
+ Debug
+ AnyCPU
+ {9638DA27-77C7-4B30-A730-6E7159A4A09F}
+ Library
+ Properties
+ MeadeAutostar497.UnitTests
+ MeadeAutostar497.UnitTests
+ v4.6.2
+ 512
+ true
+
+
+
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+ false
+ x64
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+ false
+
+
+
+ ..\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.3.1\lib\net45\Castle.Core.dll
+
+
+ ..\packages\Moq.4.10.1\lib\net45\Moq.dll
+
+
+ ..\packages\NUnit.3.11.0\lib\net45\nunit.framework.dll
+
+
+
+
+
+
+ ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.0\lib\netstandard1.0\System.Runtime.CompilerServices.Unsafe.dll
+
+
+
+
+ ..\packages\System.Threading.Tasks.Extensions.4.5.1\lib\portable-net45+win8+wp8+wpa81\System.Threading.Tasks.Extensions.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {64308775-bd4a-469c-bcab-3ed830b811af}
+ MeadeAutostar497
+
+
+
+
+
+
+
+
+
+ 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/MeadeAutostar497.UnitTests/Properties/AssemblyInfo.cs b/MeadeAutostar497.UnitTests/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..ef108f2
--- /dev/null
+++ b/MeadeAutostar497.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("MeadeAutostar497.UnitTests")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("MeadeAutostar497.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("9638da27-77c7-4b30-a730-6e7159a4a09f")]
+
+// 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/MeadeAutostar497.UnitTests/TelescopeControllerUnitTests.cs b/MeadeAutostar497.UnitTests/TelescopeControllerUnitTests.cs
new file mode 100644
index 0000000..97f4fcf
--- /dev/null
+++ b/MeadeAutostar497.UnitTests/TelescopeControllerUnitTests.cs
@@ -0,0 +1,556 @@
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.IO.Ports;
+using ASCOM;
+using ASCOM.DeviceInterface;
+using ASCOM.MeadeAutostar497.Controller;
+using Moq;
+using NUnit.Framework;
+
+namespace MeadeAutostar497.UnitTests
+{
+ [TestFixture]
+ public class TelescopeControllerUnitTests
+ {
+ private Mock serialMock;
+
+ private readonly List _availableComPorts = new List { "COM1", "COM2", "COM3" };
+ private TelescopeController _telescopeController;
+
+ private string _stringToRecieve = string.Empty;
+ private bool _isConnected = false;
+
+ [SetUp]
+ public void Setup()
+ {
+ _stringToRecieve = string.Empty;
+ _isConnected = false;
+
+ serialMock = new Mock();
+ serialMock.SetupAllProperties();
+ serialMock.Setup(x => x.GetPortNames()).Returns(() => _availableComPorts.ToArray());
+ serialMock.Setup(x => x.CommandTerminated(It.IsAny(), It.IsAny()))
+ .Returns(() => _stringToRecieve);
+ serialMock.Setup(x => x.IsOpen).Returns(() => _isConnected);
+
+ //Todo inject the serialMock instead of using a singleton to increase code stability.
+ _telescopeController = TelescopeController.Instance;
+ _telescopeController.SerialPort = serialMock.Object;
+ }
+
+ [TearDown]
+ public void TearDown()
+ {
+ _isConnected = false;
+ _telescopeController.Connected = false;
+ _telescopeController.Port = "COM1";
+ }
+
+ [Test]
+ public void ImplementsExpectedInterfaces()
+ {
+ Assert.That(_telescopeController, Is.Not.Null);
+ Assert.That(_telescopeController, Is.AssignableTo());
+ }
+
+ [Test]
+ public void NotConnectedByDefault()
+ {
+ Assert.That(_telescopeController.Connected, Is.False);
+ }
+
+ [Test]
+ public void ConnectedCanBeSetTrue()
+ {
+ _stringToRecieve = "test#";
+ _isConnected = true;
+
+ _telescopeController.Connected = true;
+ Assert.That(_telescopeController.Connected, Is.True);
+ }
+
+ [Test]
+ public void EnsureThatTheSerialCommunicationsAreSetCorrectly()
+ {
+ Assert.That(serialMock.Object.IsOpen, Is.False);
+
+ _stringToRecieve = "test#";
+ _telescopeController.Connected = true;
+ _isConnected = true;
+ Assert.That(_telescopeController.Connected, Is.True);
+
+ serialMock.Verify(x => x.Open(), Times.Once);
+
+ Assert.That(serialMock.Object.DtrEnable, Is.False);
+ Assert.That(serialMock.Object.RtsEnable, Is.False);
+ Assert.That(serialMock.Object.BaudRate, Is.EqualTo(9600));
+ Assert.That(serialMock.Object.DataBits, Is.EqualTo(8));
+ Assert.That(serialMock.Object.StopBits, Is.EqualTo(StopBits.One));
+ Assert.That(serialMock.Object.Parity, Is.EqualTo(Parity.None));
+ Assert.That(serialMock.Object.PortName, Is.EqualTo(_telescopeController.Port));
+ Assert.That(serialMock.Object.IsOpen, Is.True);
+
+ }
+
+ [Test]
+ public void WhenOpensComPortToNonAutostarThrowException()
+ {
+ Assert.That(serialMock.Object.IsOpen, Is.False);
+ var exception = Assert.Throws(() => { _telescopeController.Connected = true; });
+
+ Assert.That(exception.Message, Is.EqualTo("Failed to communicate with telescope."));
+
+ Assert.That(_telescopeController.Connected, Is.False);
+ }
+
+ [Test]
+ public void CannotChangeSerialPortObjectWhenConnected()
+ {
+ _stringToRecieve = "test#";
+ _isConnected = true;
+
+ _telescopeController.Connected = true;
+
+ Mock newSerialMock = new Mock();
+
+ var exception = Assert.Throws( () => { _telescopeController.SerialPort = newSerialMock.Object; });
+
+ Assert.That(exception, Is.Not.Null);
+ Assert.That(exception.Message, Is.EqualTo("Please disconnect before changing the serial engine."));
+ }
+
+ [Test]
+ public void PortIsSetToCom1ByDefault()
+ {
+ Assert.That(_telescopeController.Port, Is.EqualTo("COM1"));
+ }
+
+ [Test]
+ public void SettingPortToValidPortAllowed()
+ {
+ _telescopeController.Port = "COM2";
+
+ Assert.That(_telescopeController.Port, Is.EqualTo("COM2"));
+ }
+
+ [Test]
+ public void SettingPortToValidPortWhenConnectedFails()
+ {
+ _stringToRecieve = "test#";
+ _isConnected = true;
+
+ _telescopeController.Connected = true;
+ var exception = Assert.Throws( () => _telescopeController.Port = "COM2");
+
+ Assert.That(exception.Message, Is.EqualTo("Please disconnect from the scope before changing port."));
+
+ Assert.That(_telescopeController.Port, Is.EqualTo("COM1")); //port hasn't changed
+ }
+
+ [Test]
+ public void SettingPortToInvalidPortFails()
+ {
+ var exception = Assert.Throws(() => _telescopeController.Port = "COM5");
+
+ Assert.That(exception.Message, Is.EqualTo("Unable to select port COM5 as it does not exist."));
+
+ Assert.That(_telescopeController.Port, Is.EqualTo("COM1")); //port hasn't changed
+ }
+
+ [Test]
+ public void AbortSlewWorks()
+ {
+ _isConnected = true;
+
+ _telescopeController.Connected = true;
+
+ _telescopeController.AbortSlew();
+
+ serialMock.Verify(x => x.Command("#:Q#"), Times.Once);
+ }
+
+ [Test]
+ public void SlewingReturnTrueAsExpected()
+ {
+ _isConnected = true;
+
+ _telescopeController.Connected = true;
+
+ serialMock.Setup(x => x.CommandTerminated(":D#", "#")).Returns("|");
+
+ var slewing = _telescopeController.Slewing;
+
+ Assert.That(slewing, Is.True);
+ }
+
+ [Test]
+ public void SlewingReturnFalseAsExpected()
+ {
+ _isConnected = true;
+
+ _telescopeController.Connected = true;
+
+ serialMock.Setup(x => x.CommandTerminated(":D#", "#")).Returns(string.Empty);
+
+ var slewing = _telescopeController.Slewing;
+
+ Assert.That(slewing, Is.False);
+ }
+
+ [Test]
+ public void utcDate_Get_ReturnsExpectedValue()
+ {
+ DateTime expectedDate = new DateTime(2019, 04, 30, 11, 32, 24, DateTimeKind.Local);
+
+ var dateString = "04/30/19";
+ var timeString = "12:32:24";
+
+ _isConnected = true;
+
+ _telescopeController.Connected = true;
+
+ serialMock.Setup(x => x.CommandTerminated(":GG#", "#")).Returns("-01");
+ serialMock.Setup(x => x.CommandTerminated(":GC#", "#")).Returns(dateString);
+ serialMock.Setup(x => x.CommandTerminated(":GL#", "#")).Returns(timeString);
+
+ var result = _telescopeController.utcDate;
+
+ Assert.That(result, Is.EqualTo(expectedDate));
+ }
+
+ [Test]
+ public void utcDate_Set_SetsTelescopeDateAndTime()
+ {
+ DateTime testDateTime = new DateTime(2019, 04, 30, 19, 53, 32, DateTimeKind.Utc);
+
+ serialMock.Setup(x => x.CommandTerminated(":GG#", "#")).Returns("-01");
+ serialMock.Setup(x => x.CommandChar($":SL{testDateTime.Hour+1:00}:{testDateTime.Minute:00}:{testDateTime.Second:00}#")).Returns('1');
+ serialMock.Setup(x => x.CommandChar($":SC{testDateTime.Month:00}/{testDateTime.Day:00}/{testDateTime:yy}#")).Returns('1');
+
+ _isConnected = true;
+
+ _telescopeController.Connected = true;
+
+ _telescopeController.utcDate = testDateTime;
+ }
+
+ [Test]
+ public void utcDate_Set_ThrowsExceptionWhenTimeInvalid()
+ {
+ DateTime testDateTime = new DateTime(2019, 04, 30, 19, 53, 32, DateTimeKind.Utc);
+
+ serialMock.Setup(x => x.CommandTerminated(":GG#", "#")).Returns("-01");
+ //serialMock.Setup(x => x.CommandChar($":SL{testDateTime.Hour:00}:{testDateTime.Minute:00}:{testDateTime.Second:00}#")).Returns('1');
+ serialMock.Setup(x => x.CommandChar($":SC{testDateTime.Month:00}/{testDateTime.Day:00}/{testDateTime:yy}#")).Returns('1');
+
+ _isConnected = true;
+
+ _telescopeController.Connected = true;
+
+ var exception = Assert.Throws( () => {_telescopeController.utcDate = testDateTime; });
+
+ Assert.That( exception.Message, Is.EqualTo("Failed to set local time"));
+ }
+
+ [Test]
+ public void utcDate_Set_ThrowsExceptionWhenDateInvalid()
+ {
+ DateTime testDateTime = new DateTime(2019, 04, 30, 19, 53, 32, DateTimeKind.Local);
+
+ serialMock.Setup(x => x.CommandTerminated(":GG#", "#")).Returns("-01");
+ serialMock.Setup(x => x.CommandChar($":SL{testDateTime.Hour+1:00}:{testDateTime.Minute:00}:{testDateTime.Second:00}#")).Returns('1');
+ //serialMock.Setup(x => x.CommandChar($":SC{testDateTime.Month:00}/{testDateTime.Day:00}/{testDateTime:yy}#")).Returns('1');
+
+ _isConnected = true;
+
+ _telescopeController.Connected = true;
+
+ var exception = Assert.Throws(() => { _telescopeController.utcDate = testDateTime; });
+
+ Assert.That(exception.Message, Is.EqualTo("Failed to set local date"));
+ }
+
+ [TestCase("+12*34", 12.566666666666666)]
+ [TestCase("+12*34.56", 12.582222222222223)]
+ [TestCase("-67*34.56", -67.582222222222214)]
+ public void SiteLatitude_Get_ReturnsExpectedDouble( string latitude, double expectedResult)
+ {
+ serialMock.Setup(x => x.CommandTerminated(":Gt#", "#")).Returns(latitude);
+
+ _isConnected = true;
+
+ _telescopeController.Connected = true;
+
+ var result = _telescopeController.SiteLatitude;
+
+ Assert.That(result, Is.EqualTo(expectedResult));
+ }
+
+ [Test]
+ public void SiteLatitude_Set_ThrowsExeptionWhenValueTooSmall()
+ {
+ _isConnected = true;
+
+ _telescopeController.Connected = true;
+
+ var exception = Assert.Throws( () => { _telescopeController.SiteLatitude = -91;});
+
+ Assert.That(exception.Message, Is.EqualTo("Latitude cannot be less than -90 degrees."));
+ }
+
+ [Test]
+ public void SiteLatitude_Set_ThrowsExeptionWhenValueTooLarge()
+ {
+ _isConnected = true;
+
+ _telescopeController.Connected = true;
+
+ var exception = Assert.Throws(() => { _telescopeController.SiteLatitude = 91; });
+
+ Assert.That(exception.Message, Is.EqualTo("Latitude cannot be greater than 90 degrees."));
+ }
+
+ [Test]
+ public void SiteLatitude_Set_ThrowsExeptionWhenTelescopeReportsFail()
+ {
+ _isConnected = true;
+
+ _telescopeController.Connected = true;
+
+ var exception = Assert.Throws(() => { _telescopeController.SiteLatitude = 10; });
+
+ Assert.That(exception.Message, Is.EqualTo("Failed to set site latitude."));
+ }
+
+ [Test]
+ public void SiteLatitude_Set_NoErrorWhenValidValueSentSuccessfully()
+ {
+ serialMock.Setup(x => x.CommandChar(":Sts10*00#")).Returns('1');
+
+ _isConnected = true;
+
+ _telescopeController.Connected = true;
+
+ _telescopeController.SiteLatitude = 10;
+ }
+
+
+ [TestCase("012*34", 12.566666666666666)]
+ [TestCase("012:34.56", 12.582222222222223)]
+ [TestCase("350:34.56", -9.4177777777777578)]
+ public void SiteLongitude_Get_ReturnsExpectedDouble(string longitude, double expectedResult)
+ {
+ serialMock.Setup(x => x.CommandTerminated(":Gg#", "#")).Returns(longitude);
+
+ _isConnected = true;
+
+ _telescopeController.Connected = true;
+
+ var result = _telescopeController.SiteLongitude;
+
+ Assert.That(result, Is.EqualTo(expectedResult));
+ }
+
+ [Test]
+ public void SiteLongitude_Set_ThrowsExeptionWhenValueTooSmall()
+ {
+ _isConnected = true;
+
+ _telescopeController.Connected = true;
+
+ var exception = Assert.Throws(() => { _telescopeController.SiteLongitude = -181; });
+
+ Assert.That(exception.Message, Is.EqualTo("Longitude cannot be lower than -180 degrees."));
+ }
+
+ [Test]
+ public void SiteLongitude_Set_ThrowsExeptionWhenValueTooLarge()
+ {
+ _isConnected = true;
+
+ _telescopeController.Connected = true;
+
+ var exception = Assert.Throws(() => { _telescopeController.SiteLongitude = 181; });
+
+ Assert.That(exception.Message, Is.EqualTo("Longitude cannot be greater than 180 degrees."));
+ }
+
+ [Test]
+ public void SiteLongitude_Set_ThrowsExeptionWhenTelescopeReportsFail()
+ {
+ _isConnected = true;
+
+ _telescopeController.Connected = true;
+
+ var exception = Assert.Throws(() => { _telescopeController.SiteLongitude = 10; });
+
+ Assert.That(exception.Message, Is.EqualTo("Failed to set site longitude."));
+ }
+
+ [Test]
+ public void SiteLongitude_Set_NoErrorWhenValidValueSentSuccessfully()
+ {
+ serialMock.Setup(x => x.CommandChar(":Sg010*00#")).Returns('1');
+
+ _isConnected = true;
+
+ _telescopeController.Connected = true;
+
+ _telescopeController.SiteLongitude = 10;
+ }
+
+ [Test]
+ public void PulseGuideEast()
+ {
+ _isConnected = true;
+
+ _telescopeController.Connected = true;
+
+ _telescopeController.PulseGuide(GuideDirections.guideEast,100);
+
+ serialMock.Verify( x => x.Command(":Mge0100#"), Times.Once);
+ }
+
+ [Test]
+ public void PulseGuideWest()
+ {
+ _isConnected = true;
+
+ _telescopeController.Connected = true;
+
+ _telescopeController.PulseGuide(GuideDirections.guideWest, 1200);
+
+ serialMock.Verify(x => x.Command(":Mgw1200#"), Times.Once);
+ }
+
+ [Test]
+ public void PulseGuideNorth()
+ {
+ _isConnected = true;
+
+ _telescopeController.Connected = true;
+
+ _telescopeController.PulseGuide(GuideDirections.guideNorth, 256);
+
+ serialMock.Verify(x => x.Command(":Mgn0256#"), Times.Once);
+ }
+
+ [Test]
+ public void PulseGuideSouth()
+ {
+ _isConnected = true;
+
+ _telescopeController.Connected = true;
+
+ _telescopeController.PulseGuide(GuideDirections.guideSouth, 1024);
+
+ serialMock.Verify(x => x.Command(":Mgs1024#"), Times.Once);
+ }
+
+ [TestCase('A', AlignmentModes.algAltAz)]
+ [TestCase('P', AlignmentModes.algPolar)]
+ public void AlignmentMode_Get_ReturnsExpectedValue(char commandResponse, AlignmentModes mode)
+ {
+ const char ack = (char)6;
+
+ serialMock.Setup(x => x.CommandChar(ack.ToString())).Returns(commandResponse);
+
+ _isConnected = true;
+
+ _telescopeController.Connected = true;
+
+ var result = _telescopeController.AlignmentMode;
+
+ Assert.That(result, Is.EqualTo(mode));
+ }
+
+ [TestCase(AlignmentModes.algAltAz, ":AA#")]
+ [TestCase(AlignmentModes.algPolar, ":AP#")]
+ [TestCase(AlignmentModes.algGermanPolar, ":AP#")]
+ public void AligmentMode_Set_WorksAsExpected(AlignmentModes mode, string command)
+ {
+ _isConnected = true;
+
+ _telescopeController.Connected = true;
+
+ _telescopeController.AlignmentMode = mode;
+
+ serialMock.Verify( x => x.Command(command), Times.Once);
+ }
+
+ [Test]
+ public void AtParkIsFalseByDefault()
+ {
+ _isConnected = true;
+ _telescopeController.Connected = true;
+
+ Assert.That( _telescopeController.AtPark, Is.False );
+ }
+
+ [Test]
+ public void AtParkIsTrueAfterParkingScope()
+ {
+ _isConnected = true;
+
+ _telescopeController.Connected = true;
+ _telescopeController.Park();
+
+ Assert.That(_telescopeController.AtPark, Is.True);
+ }
+
+ [Test]
+ public void Park_CallingParkSendsTheParkCommand()
+ {
+ _isConnected = true;
+
+ _telescopeController.Connected = true;
+ _telescopeController.Park();
+
+ serialMock.Verify( x => x.Command(":hP#"), Times.Once);
+ }
+
+ [Test]
+ public void Park_ParkingSecondTimeDoesNothing()
+ {
+ _isConnected = true;
+
+ _telescopeController.Connected = true;
+ _telescopeController.Park();
+
+ _telescopeController.Park();
+
+ serialMock.Verify(x => x.Command(":hP#"), Times.Once);
+ }
+
+ [TestCase("356*13",356.21666666666664)]
+ [TestCase("356*13'21", 356.22249999999997)]
+ public void Azimuth_CanGetValue( string response, double expectedResult )
+ {
+ serialMock.Setup(x => x.CommandTerminated(":GZ#", "#")).Returns(response);
+
+ _isConnected = true;
+
+ _telescopeController.Connected = true;
+
+ var az = _telescopeController.Azimuth;
+
+ Assert.That( az, Is.EqualTo(expectedResult));
+ }
+
+ [TestCase("+75*13", 75.2166666666666654)]
+ [TestCase("+65*13'21", 65.222499999999997)]
+ public void Declination_CanGetValue(string response, double expectedResult)
+ {
+ serialMock.Setup(x => x.CommandTerminated(":GD#", "#")).Returns(response);
+
+ _isConnected = true;
+
+ _telescopeController.Connected = true;
+
+ var result = _telescopeController.Declination;
+
+ Assert.That(result, Is.EqualTo(expectedResult));
+ }
+ }
+}
diff --git a/MeadeAutostar497.UnitTests/packages.config b/MeadeAutostar497.UnitTests/packages.config
new file mode 100644
index 0000000..e7172db
--- /dev/null
+++ b/MeadeAutostar497.UnitTests/packages.config
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/MeadeAutostar497.sln b/MeadeAutostar497.sln
index d98a188..69570e9 100644
--- a/MeadeAutostar497.sln
+++ b/MeadeAutostar497.sln
@@ -5,16 +5,40 @@ VisualStudioVersion = 15.0.28307.136
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MeadeAutostar497", "MeadeAutostar497\MeadeAutostar497.csproj", "{64308775-BD4A-469C-BCAB-3ED830B811AF}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MeadeAutostar497.UnitTests", "MeadeAutostar497.UnitTests\MeadeAutostar497.UnitTests.csproj", "{9638DA27-77C7-4B30-A730-6E7159A4A09F}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestConsole", "TestConsole\TestConsole.csproj", "{D5207217-61C7-4E94-8097-91DBACE57D2A}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
+ Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
+ Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{64308775-BD4A-469C-BCAB-3ED830B811AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{64308775-BD4A-469C-BCAB-3ED830B811AF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {64308775-BD4A-469C-BCAB-3ED830B811AF}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {64308775-BD4A-469C-BCAB-3ED830B811AF}.Debug|x86.Build.0 = Debug|Any CPU
{64308775-BD4A-469C-BCAB-3ED830B811AF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{64308775-BD4A-469C-BCAB-3ED830B811AF}.Release|Any CPU.Build.0 = Release|Any CPU
+ {64308775-BD4A-469C-BCAB-3ED830B811AF}.Release|x86.ActiveCfg = Release|Any CPU
+ {64308775-BD4A-469C-BCAB-3ED830B811AF}.Release|x86.Build.0 = Release|Any CPU
+ {9638DA27-77C7-4B30-A730-6E7159A4A09F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9638DA27-77C7-4B30-A730-6E7159A4A09F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9638DA27-77C7-4B30-A730-6E7159A4A09F}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {9638DA27-77C7-4B30-A730-6E7159A4A09F}.Debug|x86.Build.0 = Debug|Any CPU
+ {9638DA27-77C7-4B30-A730-6E7159A4A09F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9638DA27-77C7-4B30-A730-6E7159A4A09F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9638DA27-77C7-4B30-A730-6E7159A4A09F}.Release|x86.ActiveCfg = Release|Any CPU
+ {9638DA27-77C7-4B30-A730-6E7159A4A09F}.Release|x86.Build.0 = Release|Any CPU
+ {D5207217-61C7-4E94-8097-91DBACE57D2A}.Debug|Any CPU.ActiveCfg = Debug|x86
+ {D5207217-61C7-4E94-8097-91DBACE57D2A}.Debug|x86.ActiveCfg = Debug|x86
+ {D5207217-61C7-4E94-8097-91DBACE57D2A}.Debug|x86.Build.0 = Debug|x86
+ {D5207217-61C7-4E94-8097-91DBACE57D2A}.Release|Any CPU.ActiveCfg = Release|x86
+ {D5207217-61C7-4E94-8097-91DBACE57D2A}.Release|x86.ActiveCfg = Release|x86
+ {D5207217-61C7-4E94-8097-91DBACE57D2A}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/MeadeAutostar497/AscomClasses/Rates.cs b/MeadeAutostar497/AscomClasses/Rates.cs
index 233bf9d..bd29429 100644
--- a/MeadeAutostar497/AscomClasses/Rates.cs
+++ b/MeadeAutostar497/AscomClasses/Rates.cs
@@ -99,11 +99,13 @@ namespace ASCOM.MeadeAutostar497
case TelescopeAxes.axisPrimary:
// TODO Initialize this array with any Primary axis rates that your driver may provide
// Example: m_Rates = new Rate[] { new Rate(10.5, 30.2), new Rate(54.0, 43.6) }
- this.rates = new Rate[0];
+ //this.rates = new Rate[0];
+ this.rates = new Rate[] {new Rate(1, 1), new Rate(2, 2), new Rate(3, 3), new Rate(4, 4)};
break;
case TelescopeAxes.axisSecondary:
// TODO Initialize this array with any Secondary axis rates that your driver may provide
- this.rates = new Rate[0];
+ //this.rates = new Rate[0];
+ this.rates = new Rate[] { new Rate(1, 1), new Rate(2, 2), new Rate(3, 3), new Rate(4, 4) };
break;
case TelescopeAxes.axisTertiary:
// TODO Initialize this array with any Tertiary axis rates that your driver may provide
diff --git a/MeadeAutostar497/AscomClasses/Telescope.cs b/MeadeAutostar497/AscomClasses/Telescope.cs
index e7e60c2..9892ea6 100644
--- a/MeadeAutostar497/AscomClasses/Telescope.cs
+++ b/MeadeAutostar497/AscomClasses/Telescope.cs
@@ -27,11 +27,7 @@
#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;
@@ -60,7 +56,7 @@ namespace ASCOM.MeadeAutostar497
///
[Guid("58e4fe97-1760-4e22-8ecd-2225876aeefc")]
[ClassInterface(ClassInterfaceType.None)]
- public class Telescope : ITelescopeV3
+ public class Telescope : ITelescopeV3, IFocuserV3
{
private ITelescopeController _telescopeController;
@@ -73,7 +69,7 @@ namespace ASCOM.MeadeAutostar497
///
/// Driver description that displays in the ASCOM Chooser.
///
- private static string driverDescription = "ASCOM Telescope Driver for Meade Autostar 497 based telescopes.";
+ private static string driverDescription = "Meade Autostar 497 .net";
internal static string comPortProfileName = "COM Port"; // Constants used for Profile persistence
internal static string comPortDefault = "COM1";
@@ -169,9 +165,9 @@ namespace ASCOM.MeadeAutostar497
{
CheckConnected("CommandBlind");
// Call CommandString and return as soon as it finishes
- this.CommandString(command, raw);
+ //this.CommandString(command, raw);
// or
- //throw new ASCOM.MethodNotImplementedException("CommandBlind");
+ throw new ASCOM.MethodNotImplementedException("CommandBlind");
// DO NOT have both these sections! One or the other
}
@@ -187,8 +183,11 @@ namespace ASCOM.MeadeAutostar497
public string CommandString(string command, bool raw)
{
+ // it's a good idea to put all the low level communication with the device here,
+ // then all communication calls this function
+ // you need something to ensure that only one command is in progress at a time
CheckConnected("CommandString");
- return _telescopeController.CommandString(command, raw);
+ throw new ASCOM.MethodNotImplementedException("CommandString");
}
public void Dispose()
@@ -221,6 +220,7 @@ namespace ASCOM.MeadeAutostar497
if (value)
{
LogMessage("Connected Set", "Connecting to port {0}", comPort);
+ _telescopeController.Port = comPort;
_telescopeController.Connected = true;
}
else
@@ -289,16 +289,18 @@ namespace ASCOM.MeadeAutostar497
#region ITelescope Implementation
public void AbortSlew()
{
- tl.LogMessage("AbortSlew", "Not implemented");
- throw new ASCOM.MethodNotImplementedException("AbortSlew");
+ tl.LogMessage("AbortSlew", "Aborting slew");
+ _telescopeController.AbortSlew();
}
public AlignmentModes AlignmentMode
{
get
{
- tl.LogMessage("AlignmentMode Get", "Not implemented");
- throw new ASCOM.PropertyNotImplementedException("AlignmentMode", false);
+ tl.LogMessage("AlignmentMode Get", "Getting alignmode");
+ var alignmode = _telescopeController.AlignmentMode;
+ tl.LogMessage("AlignmentMode Get", $"alignmode = {alignmode}");
+ return alignmode;
}
}
@@ -306,8 +308,9 @@ namespace ASCOM.MeadeAutostar497
{
get
{
- tl.LogMessage("Altitude", "Not implemented");
- throw new ASCOM.PropertyNotImplementedException("Altitude", false);
+ var alt = _telescopeController.Altitude;
+ tl.LogMessage("Altitude", $"{alt}");
+ return alt;
}
}
@@ -342,8 +345,9 @@ namespace ASCOM.MeadeAutostar497
{
get
{
- tl.LogMessage("AtPark", "Get - " + false.ToString());
- return false;
+ var atPatk = _telescopeController.AtPark;
+ tl.LogMessage("AtPark", "Get - " + atPatk.ToString());
+ return atPatk;
}
}
@@ -357,8 +361,9 @@ namespace ASCOM.MeadeAutostar497
{
get
{
- tl.LogMessage("Azimuth Get", "Not implemented");
- throw new ASCOM.PropertyNotImplementedException("Azimuth", false);
+ var az = _telescopeController.Azimuth;
+ tl.LogMessage("Azimuth Get", $"{az}");
+ return az;
}
}
@@ -376,9 +381,9 @@ namespace ASCOM.MeadeAutostar497
tl.LogMessage("CanMoveAxis", "Get - " + Axis.ToString());
switch (Axis)
{
- case TelescopeAxes.axisPrimary: return false;
- case TelescopeAxes.axisSecondary: return false;
- case TelescopeAxes.axisTertiary: return false;
+ case TelescopeAxes.axisPrimary: return true; //RA or AZ
+ case TelescopeAxes.axisSecondary: return true; //Dev or Alt
+ case TelescopeAxes.axisTertiary: return false; //rotator / derotator
default: throw new InvalidValueException("CanMoveAxis", Axis.ToString(), "0 to 2");
}
}
@@ -387,8 +392,8 @@ namespace ASCOM.MeadeAutostar497
{
get
{
- tl.LogMessage("CanPark", "Get - " + false.ToString());
- return false;
+ tl.LogMessage("CanPark", "Get - " + true.ToString());
+ return true;
}
}
@@ -396,8 +401,8 @@ namespace ASCOM.MeadeAutostar497
{
get
{
- tl.LogMessage("CanPulseGuide", "Get - " + false.ToString());
- return false;
+ tl.LogMessage("CanPulseGuide", "Get - " + true.ToString());
+ return true;
}
}
@@ -459,8 +464,8 @@ namespace ASCOM.MeadeAutostar497
{
get
{
- tl.LogMessage("CanSlew", "Get - " + false.ToString());
- return false;
+ tl.LogMessage("CanSlew", "Get - " + true.ToString());
+ return true;
}
}
@@ -468,8 +473,8 @@ namespace ASCOM.MeadeAutostar497
{
get
{
- tl.LogMessage("CanSlewAltAz", "Get - " + false.ToString());
- return false;
+ tl.LogMessage("CanSlewAltAz", "Get - " + true.ToString());
+ return true;
}
}
@@ -477,8 +482,8 @@ namespace ASCOM.MeadeAutostar497
{
get
{
- tl.LogMessage("CanSlewAltAzAsync", "Get - " + false.ToString());
- return false;
+ tl.LogMessage("CanSlewAltAzAsync", "Get - " + true.ToString());
+ return true;
}
}
@@ -486,8 +491,8 @@ namespace ASCOM.MeadeAutostar497
{
get
{
- tl.LogMessage("CanSlewAsync", "Get - " + false.ToString());
- return false;
+ tl.LogMessage("CanSlewAsync", "Get - " + true.ToString());
+ return true;
}
}
@@ -495,8 +500,8 @@ namespace ASCOM.MeadeAutostar497
{
get
{
- tl.LogMessage("CanSync", "Get - " + false.ToString());
- return false;
+ tl.LogMessage("CanSync", "Get - " + true.ToString());
+ return true;
}
}
@@ -522,7 +527,7 @@ namespace ASCOM.MeadeAutostar497
{
get
{
- double declination = 0.0;
+ double declination = _telescopeController.Declination;
tl.LogMessage("Declination", "Get - " + utilities.DegreesToDMS(declination, ":", ":"));
return declination;
}
@@ -620,34 +625,35 @@ namespace ASCOM.MeadeAutostar497
{
get
{
- tl.LogMessage("IsPulseGuiding Get", "Not implemented");
- throw new ASCOM.PropertyNotImplementedException("IsPulseGuiding", false);
+ tl.LogMessage("IsPulseGuiding Get", "pulse guiding is synchronous for this driver");
+ //throw new ASCOM.PropertyNotImplementedException("IsPulseGuiding", false);
+ return false;
}
}
public void MoveAxis(TelescopeAxes Axis, double Rate)
{
- tl.LogMessage("MoveAxis", "Not implemented");
- throw new ASCOM.MethodNotImplementedException("MoveAxis");
+ tl.LogMessage("MoveAxis", $"Axis={Axis} rate={Rate}");
+ _telescopeController.MoveAxis(Axis, Rate);
}
public void Park()
{
- tl.LogMessage("Park", "Not implemented");
- throw new ASCOM.MethodNotImplementedException("Park");
+ tl.LogMessage("Park", "Parking telescope");
+ _telescopeController.Park();
}
public void PulseGuide(GuideDirections Direction, int Duration)
{
- tl.LogMessage("PulseGuide", "Not implemented");
- throw new ASCOM.MethodNotImplementedException("PulseGuide");
+ tl.LogMessage("PulseGuide", $"pulse guide direction {Direction} duration {Duration}");
+ _telescopeController.PulseGuide(Direction, Duration);
}
public double RightAscension
{
get
{
- double rightAscension = 0.0;
+ double rightAscension = _telescopeController.RightAscension;
tl.LogMessage("RightAscension", "Get - " + utilities.HoursToHMS(rightAscension));
return rightAscension;
}
@@ -732,13 +738,14 @@ namespace ASCOM.MeadeAutostar497
{
get
{
- tl.LogMessage("SiteLatitude Get", "Not implemented");
- throw new ASCOM.PropertyNotImplementedException("SiteLatitude", false);
+ var siteLatitude = _telescopeController.SiteLatitude;
+ tl.LogMessage("SiteLatitude Get", $"{utilities.DegreesToDMS(siteLatitude)}");
+ return siteLatitude;
}
set
{
- tl.LogMessage("SiteLatitude Set", "Not implemented");
- throw new ASCOM.PropertyNotImplementedException("SiteLatitude", true);
+ tl.LogMessage("SiteLatitude Set", $"{utilities.DegreesToDMS(value)}");
+ _telescopeController.SiteLatitude = value;
}
}
@@ -746,13 +753,14 @@ namespace ASCOM.MeadeAutostar497
{
get
{
- tl.LogMessage("SiteLongitude Get", "Not implemented");
- throw new ASCOM.PropertyNotImplementedException("SiteLongitude", false);
+ var siteLongitude = _telescopeController.SiteLongitude;
+ tl.LogMessage("SiteLongitude Get", $"{utilities.DegreesToDMS(siteLongitude)}");
+ return siteLongitude;
}
set
{
- tl.LogMessage("SiteLongitude Set", "Not implemented");
- throw new ASCOM.PropertyNotImplementedException("SiteLongitude", true);
+ tl.LogMessage("SiteLongitude Set", $"{utilities.DegreesToDMS(value)}");
+ _telescopeController.SiteLongitude = value;
}
}
@@ -772,46 +780,48 @@ namespace ASCOM.MeadeAutostar497
public void SlewToAltAz(double Azimuth, double Altitude)
{
- tl.LogMessage("SlewToAltAz", "Not implemented");
- throw new ASCOM.MethodNotImplementedException("SlewToAltAz");
+ tl.LogMessage("SlewToAltAz", $"Az=~{Azimuth} Alt={Altitude}");
+ _telescopeController.SlewToAltAz(Azimuth, Altitude);
}
public void SlewToAltAzAsync(double Azimuth, double Altitude)
{
- tl.LogMessage("SlewToAltAzAsync", "Not implemented");
- throw new ASCOM.MethodNotImplementedException("SlewToAltAzAsync");
+ tl.LogMessage("SlewToAltAzAsync", $"Az=~{Azimuth} Alt={Altitude}");
+ _telescopeController.SlewToAltAzAsync(Azimuth, Altitude);
}
public void SlewToCoordinates(double RightAscension, double Declination)
{
- tl.LogMessage("SlewToCoordinates", "Not implemented");
- throw new ASCOM.MethodNotImplementedException("SlewToCoordinates");
+ tl.LogMessage("SlewToCoordinates", $"Ra={RightAscension}, Dec={Declination}");
+ _telescopeController.SlewToCoordinates(RightAscension, Declination);
}
public void SlewToCoordinatesAsync(double RightAscension, double Declination)
{
- tl.LogMessage("SlewToCoordinatesAsync", "Not implemented");
- throw new ASCOM.MethodNotImplementedException("SlewToCoordinatesAsync");
+ tl.LogMessage("SlewToCoordinatesAsync", $"Ra={RightAscension}, Dec={Declination}");
+ _telescopeController.SlewToCoordinatesAsync(RightAscension, Declination);
}
public void SlewToTarget()
{
- tl.LogMessage("SlewToTarget", "Not implemented");
- throw new ASCOM.MethodNotImplementedException("SlewToTarget");
+ tl.LogMessage("SlewToTarget", "Executing");
+ _telescopeController.SlewToTarget();
}
public void SlewToTargetAsync()
{
- tl.LogMessage("SlewToTargetAsync", "Not implemented");
- throw new ASCOM.MethodNotImplementedException("SlewToTargetAsync");
+ tl.LogMessage("SlewToTargetAsync", "Executing");
+ _telescopeController.SlewToTargetAsync();
}
public bool Slewing
{
get
{
- tl.LogMessage("Slewing Get", "Not implemented");
- throw new ASCOM.PropertyNotImplementedException("Slewing", false);
+ tl.LogMessage("Slewing Get", "Started");
+ var result = _telescopeController.Slewing;
+ tl.LogMessage("Slewing Get", $"Result = {result}");
+ return result;
}
}
@@ -823,27 +833,31 @@ namespace ASCOM.MeadeAutostar497
public void SyncToCoordinates(double RightAscension, double Declination)
{
- tl.LogMessage("SyncToCoordinates", "Not implemented");
- throw new ASCOM.MethodNotImplementedException("SyncToCoordinates");
+ tl.LogMessage("SyncToCoordinates", $"RA={RightAscension} Dec={Declination}");
+ _telescopeController.TargetRightAscension = RightAscension;
+ _telescopeController.TargetDeclination = Declination;
+
+ SyncToTarget();
}
public void SyncToTarget()
{
- tl.LogMessage("SyncToTarget", "Not implemented");
- throw new ASCOM.MethodNotImplementedException("SyncToTarget");
+ tl.LogMessage("SyncToTarget", "Executing");
+ _telescopeController.SyncToTarget();
}
public double TargetDeclination
{
get
{
- tl.LogMessage("TargetDeclination Get", "Not implemented");
- throw new ASCOM.PropertyNotImplementedException("TargetDeclination", false);
+ var targetDec = _telescopeController.TargetDeclination;
+ tl.LogMessage("TargetDeclination Get", $"{targetDec}");
+ return targetDec;
}
set
- {
- tl.LogMessage("TargetDeclination Set", "Not implemented");
- throw new ASCOM.PropertyNotImplementedException("TargetDeclination", true);
+ {
+ tl.LogMessage("TargetDeclination Set", $"{value}");
+ _telescopeController.TargetDeclination = value;
}
}
@@ -851,13 +865,14 @@ namespace ASCOM.MeadeAutostar497
{
get
{
- tl.LogMessage("TargetRightAscension Get", "Not implemented");
- throw new ASCOM.PropertyNotImplementedException("TargetRightAscension", false);
+ var targetRa = _telescopeController.TargetRightAscension;
+ tl.LogMessage("TargetRightAscension Get", $"{targetRa}");
+ return targetRa;
}
set
{
- tl.LogMessage("TargetRightAscension Set", "Not implemented");
- throw new ASCOM.PropertyNotImplementedException("TargetRightAscension", true);
+ tl.LogMessage("TargetRightAscension Set", $"{value}");
+ _telescopeController.TargetRightAscension = value;
}
}
@@ -865,6 +880,7 @@ namespace ASCOM.MeadeAutostar497
{
get
{
+ //todo implementing this, it exists.
bool tracking = true;
tl.LogMessage("Tracking", "Get - " + tracking.ToString());
return tracking;
@@ -880,8 +896,9 @@ namespace ASCOM.MeadeAutostar497
{
get
{
- tl.LogMessage("TrackingRate Get", "Not implemented");
- throw new ASCOM.PropertyNotImplementedException("TrackingRate", false);
+ var tr = _telescopeController.TrackingRate;
+ tl.LogMessage("TrackingRate Get", $"{tr}");
+ return tr;
}
set
{
@@ -908,14 +925,17 @@ namespace ASCOM.MeadeAutostar497
{
get
{
- DateTime utcDate = DateTime.UtcNow;
- tl.LogMessage("TrackingRates", "Get - " + Format("MM/dd/yy HH:mm:ss", utcDate));
+ tl.LogMessage("UTCDate", "Get started");
+
+ var utcDate = _telescopeController.utcDate;
+ tl.LogMessage("UTCDate", "Get - " + Format("MM/dd/yy HH:mm:ss", utcDate));
return utcDate;
}
set
{
- tl.LogMessage("UTCDate Set", "Not implemented");
- throw new ASCOM.PropertyNotImplementedException("UTCDate", true);
+ tl.LogMessage("UTCDate", "Set - " + Format("MM/dd/yy HH:mm:ss", value));
+ _telescopeController.utcDate = value;
+
}
}
@@ -927,6 +947,124 @@ namespace ASCOM.MeadeAutostar497
#endregion
+ #region IFocuser Implementation
+
+ private int focuserPosition = 0; // Class level variable to hold the current focuser position
+ private const int focuserSteps = 10000;
+
+ public bool Absolute
+ {
+ get
+ {
+ tl.LogMessage("Absolute Get", true.ToString());
+ return true; // This is an absolute focuser
+ }
+ }
+
+ public void Halt()
+ {
+ tl.LogMessage("Halt", "Not implemented");
+ throw new ASCOM.MethodNotImplementedException("Halt");
+ }
+
+ public bool IsMoving
+ {
+ get
+ {
+ tl.LogMessage("IsMoving Get", false.ToString());
+ return false; // This focuser always moves instantaneously so no need for IsMoving ever to be True
+ }
+ }
+
+ public bool Link
+ {
+ get
+ {
+ tl.LogMessage("Link Get", this.Connected.ToString());
+ return this.Connected; // Direct function to the connected method, the Link method is just here for backwards compatibility
+ }
+ set
+ {
+ tl.LogMessage("Link Set", value.ToString());
+ this.Connected = value; // Direct function to the connected method, the Link method is just here for backwards compatibility
+ }
+ }
+
+ public int MaxIncrement
+ {
+ get
+ {
+ tl.LogMessage("MaxIncrement Get", focuserSteps.ToString());
+ return focuserSteps; // Maximum change in one move
+ }
+ }
+
+ public int MaxStep
+ {
+ get
+ {
+ tl.LogMessage("MaxStep Get", focuserSteps.ToString());
+ return focuserSteps; // Maximum extent of the focuser, so position range is 0 to 10,000
+ }
+ }
+
+ public void Move(int Position)
+ {
+ tl.LogMessage("Move", Position.ToString());
+ focuserPosition = Position; // Set the focuser position
+ }
+
+ public int Position
+ {
+ get
+ {
+ return focuserPosition; // Return the focuser position
+ }
+ }
+
+ public double StepSize
+ {
+ get
+ {
+ tl.LogMessage("StepSize Get", "Not implemented");
+ throw new ASCOM.PropertyNotImplementedException("StepSize", false);
+ }
+ }
+
+ public bool TempComp
+ {
+ get
+ {
+ tl.LogMessage("TempComp Get", false.ToString());
+ return false;
+ }
+ set
+ {
+ tl.LogMessage("TempComp Set", "Not implemented");
+ throw new ASCOM.PropertyNotImplementedException("TempComp", false);
+ }
+ }
+
+ public bool TempCompAvailable
+ {
+ get
+ {
+ tl.LogMessage("TempCompAvailable Get", false.ToString());
+ return false; // Temperature compensation is not available in this driver
+ }
+ }
+
+ public double Temperature
+ {
+ get
+ {
+ tl.LogMessage("Temperature Get", "Not implemented");
+ throw new ASCOM.PropertyNotImplementedException("Temperature", false);
+ }
+ }
+
+ #endregion
+
#region Private properties and methods
// here are some useful properties and methods that can be used as required
// to help with driver development
@@ -943,16 +1081,29 @@ namespace ASCOM.MeadeAutostar497
/// If true, registers the driver, otherwise unregisters it.
private static void RegUnregASCOM(bool bRegister)
{
- using (var P = new ASCOM.Utilities.Profile())
+ using (var p = new ASCOM.Utilities.Profile())
{
- P.DeviceType = "Telescope";
+ p.DeviceType = "Telescope";
if (bRegister)
{
- P.Register(driverID, driverDescription);
+ p.Register(driverID, driverDescription);
}
else
{
- P.Unregister(driverID);
+ p.Unregister(driverID);
+ }
+ }
+
+ using (var p = new ASCOM.Utilities.Profile())
+ {
+ p.DeviceType = "Focuser";
+ if (bRegister)
+ {
+ p.Register(driverID, driverDescription);
+ }
+ else
+ {
+ p.Unregister(driverID);
}
}
}
diff --git a/MeadeAutostar497/Controller/ISerialProcessor.cs b/MeadeAutostar497/Controller/ISerialProcessor.cs
new file mode 100644
index 0000000..5578bf3
--- /dev/null
+++ b/MeadeAutostar497/Controller/ISerialProcessor.cs
@@ -0,0 +1,28 @@
+using System.IO.Ports;
+using System.Runtime.InteropServices;
+
+namespace ASCOM.MeadeAutostar497.Controller
+{
+ [ComVisible(false)]
+ public interface ISerialProcessor
+ {
+ bool IsOpen { get; }
+ bool DtrEnable { get; set; }
+ bool RtsEnable { get; set; }
+ int BaudRate { get; set; }
+ int DataBits { get; set; }
+ StopBits StopBits { get; set; }
+ Parity Parity { get; set; }
+ string PortName { get; set; }
+ string[] GetPortNames();
+ void Open();
+ void Close();
+
+ string CommandTerminated(string command, string terminator);
+ char CommandChar(string command);
+ string ReadTerminated(string terminator);
+ void Command(string command);
+ void Lock();
+ void Unlock();
+ }
+}
\ No newline at end of file
diff --git a/MeadeAutostar497/Controller/ITelescopeController.cs b/MeadeAutostar497/Controller/ITelescopeController.cs
index 2cbea84..06698ea 100644
--- a/MeadeAutostar497/Controller/ITelescopeController.cs
+++ b/MeadeAutostar497/Controller/ITelescopeController.cs
@@ -1,13 +1,36 @@
-using ASCOM.Utilities.Interfaces;
+using System;
+using ASCOM.DeviceInterface;
namespace ASCOM.MeadeAutostar497.Controller
{
public interface ITelescopeController
{
- ISerial SerialPort { get; set; }
string Port { get; set; }
bool Connected { get; set; }
- string CommandString(string command, bool raw);
+ bool Slewing { get; }
+ DateTime utcDate { get; set; }
+ double SiteLatitude { get; set; }
+ double SiteLongitude { get; set; }
+ AlignmentModes AlignmentMode { get; set; }
+ bool AtPark { get; }
+ double Altitude { get; }
+ double Azimuth { get; }
+ double RightAscension { get; }
+ double Declination { get; }
+ double TargetRightAscension { get; set; }
+ double TargetDeclination { get; set; }
+ DriveRates TrackingRate { get; }
+ void AbortSlew();
+ void PulseGuide(GuideDirections direction, int duration);
+ void Park();
+ void SlewToCoordinates(double rightAscension, double declination);
+ void SlewToCoordinatesAsync(double rightAscension, double declination);
+ void SlewToAltAz(double azimuth, double altitude);
+ void SlewToAltAzAsync(double azimuth, double altitude);
+ void SyncToTarget();
+ void SlewToTarget();
+ void SlewToTargetAsync();
+ void MoveAxis(TelescopeAxes axis, double rate);
}
}
\ No newline at end of file
diff --git a/MeadeAutostar497/Controller/SerialProcessor.cs b/MeadeAutostar497/Controller/SerialProcessor.cs
new file mode 100644
index 0000000..1c77556
--- /dev/null
+++ b/MeadeAutostar497/Controller/SerialProcessor.cs
@@ -0,0 +1,142 @@
+using System;
+using System.IO.Ports;
+using System.Runtime.InteropServices;
+using System.Threading;
+
+namespace ASCOM.MeadeAutostar497.Controller
+{
+ [ComVisible(false)]
+ public class SerialProcessor : ISerialProcessor
+ {
+ private SerialPort _serialPort = new SerialPort();
+ private Mutex serialMutex = new Mutex();
+
+ public bool IsOpen => _serialPort.IsOpen;
+
+ public bool DtrEnable
+ {
+ get => _serialPort.DtrEnable;
+ set => _serialPort.DtrEnable = value;
+ }
+
+ public bool RtsEnable
+ {
+ get => _serialPort.RtsEnable;
+ set => _serialPort.RtsEnable = value;
+ }
+
+ public int BaudRate
+ {
+ get => _serialPort.BaudRate;
+ set => _serialPort.BaudRate = value;
+ }
+
+ public int DataBits
+ {
+ get => _serialPort.DataBits;
+ set => _serialPort.DataBits = value;
+ }
+
+ public StopBits StopBits
+ {
+ get => _serialPort.StopBits;
+ set => _serialPort.StopBits = value;
+ }
+
+ public Parity Parity
+ {
+ get => _serialPort.Parity;
+ set => _serialPort.Parity = value;
+ }
+
+ public string PortName
+ {
+ get => _serialPort.PortName;
+ set => _serialPort.PortName = value;
+ }
+
+ public string[] GetPortNames()
+ {
+ return SerialPort.GetPortNames();
+ }
+
+ public void Open()
+ {
+ _serialPort.ReadTimeout = 5000;
+ _serialPort.WriteTimeout = 5000;
+ _serialPort.Open();
+ }
+
+ public void Close()
+ {
+ _serialPort.Close();
+ }
+
+ public string CommandTerminated(string command, string terminator)
+ {
+ Lock();
+ try
+ {
+ _serialPort.Write(command);
+ string result = _serialPort.ReadTo("#");
+ return result;
+ }
+ finally
+ {
+ Unlock();
+ }
+ }
+
+ public char CommandChar(string command)
+ {
+ Lock();
+ try
+ {
+ _serialPort.Write(command);
+ var result = _serialPort.ReadChar();
+ return Convert.ToChar(result);
+ }
+ finally
+ {
+ Unlock();
+ }
+ }
+
+ public string ReadTerminated(string terminator)
+ {
+ Lock();
+ try
+ {
+ string result = _serialPort.ReadTo("#");
+ return result;
+ }
+ finally
+ {
+ Unlock();
+ }
+ }
+
+ public void Command(string command)
+ {
+ Lock();
+ try
+ {
+ _serialPort.Write(command);
+ }
+ finally
+ {
+ Unlock();
+ }
+ }
+
+ public void Lock()
+ {
+ serialMutex.WaitOne();
+ }
+
+ public void Unlock()
+ {
+ serialMutex.ReleaseMutex();
+ }
+ }
+}
diff --git a/MeadeAutostar497/Controller/TelescopeController.cs b/MeadeAutostar497/Controller/TelescopeController.cs
index 891111d..db3916d 100644
--- a/MeadeAutostar497/Controller/TelescopeController.cs
+++ b/MeadeAutostar497/Controller/TelescopeController.cs
@@ -1,19 +1,27 @@
using System;
+using System.IO.Ports;
+using System.Linq;
+using System.Threading;
+using ASCOM.DeviceInterface;
using ASCOM.Utilities;
using ASCOM.Utilities.Interfaces;
namespace ASCOM.MeadeAutostar497.Controller
{
+ //todo stop this being a singleton, and instead use a server to make only a single instance.
public sealed class TelescopeController : ITelescopeController
{
- private static readonly Lazy lazy = new Lazy();
+ private const double INVALID_PARAMETER = -1000;
- public static TelescopeController Instance => lazy.Value;
+ private static readonly Lazy Lazy = new Lazy();
- private ISerial _serialPort;
- public ISerial SerialPort
+ public static TelescopeController Instance => Lazy.Value;
+
+ //todo remove this as it can cause problems in production
+ private ISerialProcessor _serialPort;
+ public ISerialProcessor SerialPort
{
- get => _serialPort ?? (_serialPort = new Serial());
+ get => _serialPort ?? (_serialPort = new SerialProcessor());
set
{
if (_serialPort == value)
@@ -21,14 +29,27 @@ namespace ASCOM.MeadeAutostar497.Controller
if (_serialPort != null)
{
- if (_serialPort.Connected)
- throw new InvalidOperationException("Please disconnect before changing the port.");
+ if (_serialPort.IsOpen)
+ throw new InvalidOperationException("Please disconnect before changing the serial engine.");
}
_serialPort = value;
}
}
+ private IUtil _util;
+ public IUtil Util
+ {
+ get => _util ?? (_util = new Util());
+ set
+ {
+ if (Equals(_util, value))
+ return;
+
+ _util = value;
+ }
+ }
+
private string _port = "COM1";
public string Port
{
@@ -40,13 +61,21 @@ namespace ASCOM.MeadeAutostar497.Controller
if (Connected)
throw new InvalidOperationException("Please disconnect from the scope before changing port.");
+ if (!ValidPort(value))
+ throw new InvalidOperationException($"Unable to select port {value} as it does not exist.");
+
_port = value;
}
}
+ private bool ValidPort(string value)
+ {
+ return SerialPort.GetPortNames().Contains(value);
+ }
+
public bool Connected
{
- get => SerialPort.Connected;
+ get => SerialPort.IsOpen;
set
{
if (value == Connected)
@@ -55,32 +84,769 @@ namespace ASCOM.MeadeAutostar497.Controller
if (value)
{
//Connecting
- SerialPort.DTREnable = false;
- SerialPort.RTSEnable = false;
- SerialPort.Speed = SerialSpeed.ps9600;
- SerialPort.DataBits = 8;
- SerialPort.StopBits = SerialStopBits.One;
- SerialPort.Parity = SerialParity.None;
- SerialPort.PortName = Port;
- SerialPort.Connected = true;
+ try
+ {
+ AtPark = false;
+ SerialPort.DtrEnable = false;
+ SerialPort.RtsEnable = false;
+ SerialPort.BaudRate = 9600;
+ SerialPort.DataBits = 8;
+ SerialPort.StopBits = StopBits.One;
+ SerialPort.Parity = Parity.None;
+ SerialPort.PortName = Port;
+ SerialPort.Open();
- //todo perform test to ensure that connection has been made correctly.
+ TestConnectionActive();
+ }
+ catch (Exception)
+ {
+ if (SerialPort.IsOpen)
+ SerialPort.Close();
+ throw;
+ }
}
else
{
//Disconnecting
- SerialPort.Connected = false;
+ SerialPort.Close();
+ AtPark = false;
}
}
}
- public string CommandString(string command, bool raw)
+ private void TestConnectionActive()
{
- // 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
-
- throw new ASCOM.MethodNotImplementedException("CommandString");
+ var firmwareVersionNumber = SerialPort.CommandTerminated(":GVN#", "#");
+ if (string.IsNullOrEmpty(firmwareVersionNumber))
+ {
+ throw new InvalidOperationException("Failed to communicate with telescope.");
+ }
}
+
+ public bool Slewing
+ {
+ get
+ {
+ if (!Connected) return false;
+
+
+ if (movingAxis())
+ return true;
+
+ var result = SerialPort.CommandTerminated(":D#", "#");
+ return result != string.Empty;
+ }
+ }
+
+ public DateTime utcDate
+ {
+ get
+ {
+ string telescopeDate = SerialPort.CommandTerminated(":GC#", "#");
+ string telescopeTime = SerialPort.CommandTerminated(":GL#", "#");
+
+ int month = telescopeDate.Substring(0, 2).ToInteger();
+ int day = telescopeDate.Substring(3, 2).ToInteger();
+ int year = telescopeDate.Substring(6, 2).ToInteger();
+
+ if (year < 2000) //todo fix this hack that will create a Y2K100 bug
+ {
+ year = year + 2000;
+ }
+
+ int hour = telescopeTime.Substring(0, 2).ToInteger();
+ int minute = telescopeTime.Substring(3, 2).ToInteger();
+ int second = telescopeTime.Substring(6, 2).ToInteger();
+
+ var utcCorrection = GetUtcCorrection();
+
+ //Todo is this telescope local time, or real utc?
+ var newDate = new DateTime(year, month, day, hour, minute, second, DateTimeKind.Utc) + utcCorrection;
+
+ return newDate;
+ }
+ set
+ {
+ var utcCorrection = GetUtcCorrection();
+ var localDateTime = value - utcCorrection;
+
+ //Todo is this telescope local time, or real utc?
+ var timeResult = SerialPort.CommandChar($":SL{localDateTime:HH:mm:ss}#");
+ if (timeResult != '1')
+ {
+ throw new InvalidOperationException("Failed to set local time");
+ }
+
+ SerialPort.Lock();
+ try
+ {
+ var dateResult = SerialPort.CommandChar($":SC{localDateTime:MM/dd/yy}#");
+ if (dateResult != '1')
+ {
+ throw new InvalidOperationException("Failed to set local date");
+ }
+
+ //throwing away these two strings which represent
+ SerialPort.ReadTerminated("#"); //Updating Planetary Data#
+ SerialPort.ReadTerminated("#"); // #
+ }
+ finally
+ {
+ SerialPort.Unlock();
+ }
+ }
+
+ }
+
+ private TimeSpan GetUtcCorrection()
+ {
+ string utcOffSet = SerialPort.CommandTerminated(":GG#", "#");
+ double utcOffsetHours = double.Parse(utcOffSet);
+ TimeSpan utcCorrection = TimeSpan.FromHours(utcOffsetHours);
+ return utcCorrection;
+ }
+
+ public double SiteLatitude
+ {
+ get
+ {
+ var latitude = SerialPort.CommandTerminated( ":Gt#", "#");
+
+ return DmsToDouble(latitude);
+ }
+ set
+ {
+ if (value > 90)
+ throw new InvalidValueException("Latitude cannot be greater than 90 degrees.");
+
+ if (value < -90)
+ throw new InvalidValueException("Latitude cannot be less than -90 degrees.");
+
+ int d = Convert.ToInt32(Math.Floor(value));
+ int m = Convert.ToInt32(60 * (value - d));
+
+ var result = SerialPort.CommandChar($":Sts{d:00}*{m:00}#");
+ if (result != '1')
+ throw new InvalidOperationException("Failed to set site latitude.");
+ }
+ }
+
+ private double DmsToDouble(string dms)
+ {
+ if (IsNumeric(dms[0]))
+ {
+ double l = int.Parse(dms.Substring(0, 3));
+ l = l + double.Parse(dms.Substring(4, 2)) / 60;
+ if (dms.Length == 9)
+ l = l + double.Parse(dms.Substring(7, 2)) / 60 / 60;
+
+ return l;
+ }
+
+ double lat = int.Parse(dms.Substring(1, 2));
+ lat = lat + double.Parse(dms.Substring(4, 2)) / 60;
+ if (dms.Length == 9)
+ lat = lat + double.Parse(dms.Substring(7, 2)) / 60 / 60;
+
+ if (dms[0] == '-')
+ lat = -lat;
+
+ return lat;
+ }
+
+ private bool IsNumeric(char c)
+ {
+ char[] nums = new[] {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
+ return nums.Contains(c);
+ }
+
+ public double SiteLongitude
+ {
+ get
+ {
+ var longitude = SerialPort.CommandTerminated(":Gg#", "#");
+ double l = DmsToDouble(longitude);
+
+ if (l > 180)
+ l = l - 360;
+
+ return l;
+ }
+ set
+ {
+ if (value > 180)
+ throw new InvalidValueException("Longitude cannot be greater than 180 degrees.");
+
+ if (value < -180)
+ throw new InvalidValueException("Longitude cannot be lower than -180 degrees.");
+
+ int d = Convert.ToInt32(Math.Floor(value));
+ int m = Convert.ToInt32(60 * (value - d));
+
+ var result = SerialPort.CommandChar($":Sg{d:000}*{m:00}#");
+ if (result != '1')
+ throw new InvalidOperationException("Failed to set site longitude.");
+ }
+
+ }
+
+ public AlignmentModes AlignmentMode
+ {
+ get
+ {
+ const char ack = (char)6;
+ //var alignmentString = SerialPort.CommandTerminated(":GW#", "#");
+ var alignmentString = SerialPort.CommandChar(ack.ToString());
+ //: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.
+
+ switch (alignmentString)
+ {
+ case 'A': return AlignmentModes.algAltAz;
+ case 'P': return AlignmentModes.algPolar;
+ case 'G': return AlignmentModes.algGermanPolar;
+ default:
+ throw new InvalidValueException($"unknown alignment returned from telescope: {alignmentString}");
+ }
+ }
+ set
+ {
+ switch (value)
+ {
+ case AlignmentModes.algAltAz:
+ SerialPort.Command(":AA#");
+ //:AA# Sets telescope the AltAz alignment mode
+ //Returns: nothing
+ break;
+ case AlignmentModes.algPolar:
+ case AlignmentModes.algGermanPolar:
+ SerialPort.Command(":AP#");
+ //:AP# Sets telescope to Polar alignment mode
+ //Returns: nothing
+ break;
+ default:
+ throw new ArgumentOutOfRangeException(nameof(value), value, null);
+ }
+
+ //:AL# Sets telescope to Land alignment mode
+ //Returns: nothing
+ }
+ }
+
+ public bool AtPark { get; private set; }
+
+ public double Azimuth
+ {
+ get
+ {
+ var result = SerialPort.CommandTerminated(":GZ#", "#");
+ //:GZ# Get telescope azimuth
+ //Returns: DDD*MM#T or DDD*MM’SS#
+ //The current telescope Azimuth depending on the selected precision.
+
+ double az = DmsToDouble(result);
+
+ return az;
+ }
+ }
+
+ public double RightAscension {
+ get
+ {
+ var result = SerialPort.CommandTerminated(":GR#", "#");
+ //:GR# Get Telescope RA
+ //Returns: HH: MM.T# or HH:MM:SS#
+ //Depending which precision is set for the telescope
+
+ double ra = HmsToDouble(result);
+
+ return ra;
+ }
+ }
+
+ private double HmsToDouble(string hms)
+ {
+ return Util.HMSToHours(hms);
+ }
+
+ public double Declination
+ {
+ get
+ {
+ var result = SerialPort.CommandTerminated(":GD#", "#");
+ //:GD# Get Telescope Declination.
+ //Returns: sDD* MM# or sDD*MM’SS#
+ //Depending upon the current precision setting for the telescope.
+
+ double az = DmsToDouble(result);
+
+ return az;
+ }
+ }
+
+ private double _targetRightAscension = INVALID_PARAMETER;
+ public double TargetRightAscension {
+ get
+ {
+ if (_targetRightAscension == INVALID_PARAMETER)
+ throw new ASCOM.InvalidOperationException("Target not set");
+
+ //var result = SerialPort.CommandTerminated(":Gr#", "#");
+ ////:Gr# Get current/target object RA
+ ////Returns: HH: MM.T# or HH:MM:SS
+ ////Depending upon which precision is set for the telescope
+
+ //double targetRa = HmsToDouble(result);
+ //return targetRa;
+ return _targetRightAscension;
+ }
+ set
+ {
+ if (value < 0)
+ throw new InvalidValueException("Right ascension value cannot be below 0");
+
+ if (value >= 24)
+ throw new InvalidValueException("Right ascension value cannot be greater than 23:59:59");
+
+
+ //todo implement the low precision version
+
+ var hms = Util.HoursToHMS(value, ":", ":", ":", 2);
+ var response = SerialPort.CommandChar($":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.
+ // Returns:
+ //0 – Invalid
+ //1 - Valid
+
+ if (response == '0')
+ throw new InvalidOperationException("Failed to set TargetRightAscension.");
+
+ _targetRightAscension = value;
+ }
+ }
+
+ private double _targetDeclination = INVALID_PARAMETER;
+ public double TargetDeclination {
+ get
+ {
+ if (_targetDeclination == INVALID_PARAMETER)
+ throw new ASCOM.InvalidOperationException("Target not set");
+
+ //var result = SerialPort.CommandTerminated(":Gd#", "#");
+ ////:Gd# Get Currently Selected Object/Target Declination
+ ////Returns: sDD* MM# or sDD*MM’SS#
+ ////Depending upon the current precision setting for the telescope.
+
+ //double targetDec = DmsToDouble(result);
+
+ //return targetDec;
+ return _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.");
+
+
+ var dms = Util.DegreesToDMS(value, "*", ":", ":", 2);
+ var s = value < 0 ? '-' : '+';
+
+ var result = SerialPort.CommandChar($":Sd{s}{dms}#");
+ //:SdsDD*MM#
+ //Set target object declination to sDD*MM or sDD*MM:SS depending on the current precision setting
+ //Returns:
+ //1 - Dec Accepted
+ //0 – Dec invalid
+
+ if (result == '0')
+ {
+ throw new ASCOM.InvalidOperationException("Target declination invalid");
+ }
+
+ _targetDeclination = value;
+ }
+ }
+
+ public DriveRates TrackingRate
+ {
+ get
+ {
+ var result = SerialPort.CommandTerminated(":GT#", "#");
+
+ double rate = double.Parse(result);
+
+
+ if (rate == 60.1)
+ return DriveRates.driveLunar;
+ else if (rate == 60.1)
+ return DriveRates.driveSidereal;
+
+ return DriveRates.driveKing;
+ }
+ set
+ {
+ switch (value)
+ {
+ case DriveRates.driveSidereal:
+ SerialPort.Command(":TQ#");
+ //:TQ# Selects sidereal tracking rate
+ //Returns: Nothing
+ break;
+ case DriveRates.driveLunar:
+ SerialPort.Command(":TL#");
+ //:TL# Set Lunar Tracking Rage
+ //Returns: Nothing
+ break;
+ case DriveRates.driveSolar:
+ SerialPort.Command(":TS#");
+ //:TS# Select Solar tracking rate. [LS Only]
+ //Returns: Nothing
+ break;
+ case DriveRates.driveKing:
+ break;
+ default:
+ throw new ArgumentOutOfRangeException(nameof(value), value, null);
+ }
+ }
+ }
+
+ public double Altitude {
+ get
+ {
+ var result = SerialPort.CommandTerminated(":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.
+ return DmsToDouble(result);
+ }
+ }
+
+ public void AbortSlew()
+ {
+ SerialPort.Command("#:Q#");
+ }
+
+ public void PulseGuide(GuideDirections direction, int duration)
+ {
+ string d = string.Empty;
+ switch (direction)
+ {
+ case GuideDirections.guideEast:
+ d = "e";
+ break;
+ case GuideDirections.guideNorth:
+ d = "n";
+ break;
+ case GuideDirections.guideSouth:
+ d = "s";
+ break;
+ case GuideDirections.guideWest:
+ d = "w";
+ break;
+ }
+
+ if (UserNewerPulseGuiding)
+ {
+ _serialPort.Command($":Mg{d}{duration:0000}#");
+ Thread.Sleep(duration); //todo figure out if this is really needed
+ }
+ else
+ {
+ _serialPort.Command(":RG#"); //Make sure we are at guide rate
+ _serialPort.Command($":M{d}#");
+ Thread.Sleep(duration);
+ _serialPort.Command($":Q{d}#");
+
+ //classic only !!!, this is needed since once in a while one is not enough
+ Thread.Sleep(200);
+ _serialPort.Command($":Q{d}#");
+ }
+ }
+
+ public void Park()
+ {
+ if (AtPark)
+ return;
+
+ AtPark = true;
+ _serialPort.Command(":hP#");
+ }
+
+ public void SlewToCoordinates(double rightAscension, double declination)
+ {
+ SlewToCoordinatesAsync(rightAscension, declination);
+
+ while (Slewing) //wait for slew to complete
+ {
+ Util.WaitForMilliseconds(200); //be responsive to AbortSlew();
+ }
+ }
+
+ public void SlewToCoordinatesAsync(double rightAscension, double declination)
+ {
+ TargetRightAscension = rightAscension;
+ TargetDeclination = declination;
+
+ DoSlewAsync(true);
+ }
+
+ public void SlewToAltAz(double azimuth, double altitude)
+ {
+ SlewToAltAzAsync(azimuth, altitude);
+
+ while (Slewing) //wait for slew to complete
+ {
+ Util.WaitForMilliseconds(200); //be responsive to AbortSlew();
+ }
+ }
+
+ private double TargetAltitude
+ {
+ set
+ {
+ if (value > 90)
+ throw new ASCOM.InvalidValueException("Altitude cannot be greater than 90.");
+
+ if (value < 0)
+ throw new ASCOM.InvalidValueException("Altitide cannot be less than 0.");
+
+
+ var dms = Util.DegreesToDMS(value, "*", "'", ".", 2);
+ var s = value < 0 ? '-' : '+';
+
+ var result = SerialPort.CommandChar($":Sa{s}{dms}#");
+ //:SasDD*MM#
+ //Set target object altitude to sDD*MM# or sDD*MM’SS# [LX 16”, Autostar, Autostar II]
+ //Returns:
+ //1 Object within slew range
+ //0 Object out of slew range
+
+ if (result == '0')
+ throw new ASCOM.InvalidOperationException("Target altitude out of slew range");
+ }
+ }
+
+ private double TargetAzimuth
+ {
+ set
+ {
+ if (value >= 360)
+ throw new ASCOM.InvalidValueException("Azimuth cannot be 360 or higher.");
+
+ if (value < 0)
+ throw new ASCOM.InvalidValueException("Azimuth cannot be less than 0.");
+
+ var dms = Util.DegreesToDM(value, "*", ":", 2);
+
+ var result = SerialPort.CommandChar($":Sd{dms}#");
+ //:SzDDD*MM#
+ //Sets the target Object Azimuth[LX 16” and Autostar II only]
+ //Returns:
+ //0 – Invalid
+ //1 - Valid
+
+ if (result == '0')
+ throw new ASCOM.InvalidOperationException("Target Azimuth out of slew range");
+
+ }
+ }
+
+ public void SlewToAltAzAsync(double azimuth, double altitude)
+ {
+ TargetAltitude = altitude;
+ TargetAzimuth = azimuth;
+
+ DoSlewAsync(false);
+ }
+
+ public void SyncToTarget()
+ {
+ var result = SerialPort.CommandTerminated(":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'#"
+
+ if (result == string.Empty)
+ throw new ASCOM.InvalidOperationException("Unable to perform sync");
+ }
+
+ public void SlewToTarget()
+ {
+ SlewToTargetAsync();
+
+ while (Slewing)
+ {
+ Util.WaitForMilliseconds(200);
+ }
+ }
+
+ public void SlewToTargetAsync()
+ {
+ if (TargetDeclination == INVALID_PARAMETER || TargetRightAscension == INVALID_PARAMETER )
+ throw new ASCOM.InvalidOperationException("No target selected to slew to.");
+
+ DoSlewAsync(true);
+ }
+
+ private bool movingAxis()
+ {
+ return _movingPrimary || _movingSecondary;
+ }
+
+ private bool _movingPrimary;
+ private bool _movingSecondary;
+ public void MoveAxis(TelescopeAxes axis, double rate)
+ {
+ var absrate = Math.Abs(rate);
+
+ switch(absrate)
+ {
+ case 0:
+ //do nothing, it's ok this time as we're halting the slew.
+ break;
+ case 1:
+ SerialPort.Command(":RG#");
+ //:RG# Set Slew rate to Guiding Rate (slowest)
+ //Returns: Nothing
+ break;
+ case 2:
+ SerialPort.Command(":RC#");
+ //:RC# Set Slew rate to Centering rate (2nd slowest)
+ //Returns: Nothing
+ break;
+ case 3:
+ SerialPort.Command(":RM#");
+ //:RM# Set Slew rate to Find Rate (2nd Fastest)
+ //Returns: Nothing
+ break;
+ case 4:
+ SerialPort.Command(":RS#");
+ //:RS# Set Slew rate to max (fastest)
+ //Returns: Nothing
+ break;
+ default:
+ throw new ASCOM.InvalidValueException($"Rate {rate} not supported");
+
+ }
+
+ switch (axis)
+ {
+ case TelescopeAxes.axisPrimary:
+ if (rate == 0)
+ {
+ _movingPrimary = false;
+ SerialPort.Command(":Qe#");
+ //:Qe# Halt eastward Slews
+ //Returns: Nothing
+ SerialPort.Command(":Qw#");
+ //:Qw# Halt westward Slews
+ //Returns: Nothing
+ }
+ else if (rate > 0)
+ {
+ SerialPort.Command(":Me#");
+ //:Me# Move Telescope East at current slew rate
+ //Returns: Nothing
+ _movingPrimary = true;
+ }
+ else
+ {
+ SerialPort.Command(":Mw#");
+ //:Mw# Move Telescope West at current slew rate
+ //Returns: Nothing
+ _movingPrimary = true;
+ }
+ break;
+ case TelescopeAxes.axisSecondary:
+ if (rate == 0)
+ {
+ _movingSecondary = false;
+ SerialPort.Command(":Qn#");
+ //:Qn# Halt northward Slews
+ //Returns: Nothing
+ SerialPort.Command(":Qs#");
+ //:Qs# Halt southward Slews
+ //Returns: Nothing
+ }
+ else if (rate > 0)
+ {
+ SerialPort.Command(":Mn#");
+ //:Mn# Move Telescope North at current slew rate
+ //Returns: Nothing
+ _movingSecondary = true;
+ }
+ else
+ {
+ SerialPort.Command(":Ms#");
+ //:Ms# Move Telescope South at current slew rate
+ //Returns: Nothing
+ _movingSecondary = true;
+ }
+
+ break;
+ default:
+ throw new ASCOM.MethodNotImplementedException("Can not move this axis.");
+ }
+ }
+
+ //todo remove the polar parameter and split method into two.
+ private void DoSlewAsync( bool polar)
+ {
+ switch (polar)
+ {
+ case true:
+ var response = SerialPort.CommandChar(":MS#");
+ //:MS# Slew to Target Object
+ //Returns:
+ //0 Slew is Possible
+ //1# Object Below Horizon w/string message
+ //2# Object Below Higher w/string message
+
+ switch (response)
+ {
+ case '0':
+ //We're slewing everything should be working just fine.
+ break;
+ case '1':
+ //Below Horizon
+ string belowHorizonMessage = SerialPort.ReadTerminated("#");
+ throw new ASCOM.InvalidOperationException(belowHorizonMessage);
+ case '2':
+ //Below Horizon
+ string belowMinimumElevationMessage = SerialPort.ReadTerminated("#");
+ throw new ASCOM.InvalidOperationException(belowMinimumElevationMessage);
+ default:
+ throw new ASCOM.DriverException("This error should not happen");
+
+ }
+ break;
+ case false:
+ var maResponse = SerialPort.CommandChar(":MA#");
+ //:MA# Autostar, LX 16”, Autostar II – Slew to target Alt and Az
+ //Returns:
+ //0 - No fault
+ //1 – Fault
+ // LX200 – Not supported
+
+ if (maResponse == '1')
+ {
+ throw new ASCOM.InvalidOperationException("fault");
+ }
+ break;
+ }
+ }
+
+ public bool UserNewerPulseGuiding { get; set; } = true; //todo make this a device setting
}
}
diff --git a/MeadeAutostar497/MeadeAutostar497.csproj b/MeadeAutostar497/MeadeAutostar497.csproj
index 2be7529..6de6351 100644
--- a/MeadeAutostar497/MeadeAutostar497.csproj
+++ b/MeadeAutostar497/MeadeAutostar497.csproj
@@ -1,5 +1,5 @@
-
+
Debug
AnyCPU
@@ -15,7 +15,7 @@
3.5
- v4.0
+ v4.6.2
ASCOM.ico
true
ASCOMDriverTemplate.snk
@@ -34,7 +34,8 @@
false
false
true
- Client
+
+
true
@@ -45,7 +46,8 @@
prompt
4
true
- AnyCPU
+ x64
+ false
pdbonly
@@ -56,6 +58,7 @@
4
AnyCPU
false
+ false
@@ -66,6 +69,7 @@
+
@@ -74,13 +78,22 @@
+
+
+
+
+
+
+
+
+
True
diff --git a/MeadeAutostar497/Properties/AssemblyInfo.cs b/MeadeAutostar497/Properties/AssemblyInfo.cs
index 848df7f..2a06abf 100644
--- a/MeadeAutostar497/Properties/AssemblyInfo.cs
+++ b/MeadeAutostar497/Properties/AssemblyInfo.cs
@@ -8,11 +8,11 @@ using System.Runtime.InteropServices;
//
// TODO - Add your authorship information here
[assembly: AssemblyTitle("ASCOM.MeadeAutostar497.Telescope")]
-[assembly: AssemblyDescription("ASCOM Telescope driver for MeadeAutostar497")]
+[assembly: AssemblyDescription("ASCOM MeadeAutostar497 .net")]
[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("The ASCOM Initiative")]
+[assembly: AssemblyCompany("Cjdawson.com")]
[assembly: AssemblyProduct("ASCOM Telescope driver for MeadeAutostar497")]
-[assembly: AssemblyCopyright("Copyright © 2019 The ASCOM Initiative")]
+[assembly: AssemblyCopyright("Copyright © 2019 cjdawson.com")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
@@ -35,5 +35,5 @@ using System.Runtime.InteropServices;
// by using the '*' as shown below:
//
// TODO - Set your driver's version here
-[assembly: AssemblyVersion("6.4.0.0")]
-[assembly: AssemblyFileVersion("6.4.0.0")]
+[assembly: AssemblyVersion("0.0.0.0")]
+[assembly: AssemblyFileVersion("0.0.0.0")]
diff --git a/MeadeAutostar497/Properties/Resources.Designer.cs b/MeadeAutostar497/Properties/Resources.Designer.cs
index c18564b..9d71803 100644
--- a/MeadeAutostar497/Properties/Resources.Designer.cs
+++ b/MeadeAutostar497/Properties/Resources.Designer.cs
@@ -1,18 +1,17 @@
//------------------------------------------------------------------------------
//
// This code was generated by a tool.
-// Runtime Version:4.0.30319.18052
+// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
//
//------------------------------------------------------------------------------
-namespace ASCOM.MeadeAutostar497.Properties
-{
+namespace ASCOM.MeadeAutostar497.Properties {
using System;
-
-
+
+
///
/// A strongly-typed resource class, for looking up localized strings, etc.
///
@@ -20,74 +19,62 @@ namespace ASCOM.MeadeAutostar497.Properties
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- internal class Resources
- {
-
+ internal class Resources {
+
private static global::System.Resources.ResourceManager resourceMan;
-
+
private static global::System.Globalization.CultureInfo resourceCulture;
-
+
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
- internal Resources()
- {
+ internal Resources() {
}
-
+
///
/// Returns the cached ResourceManager instance used by this class.
///
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
- internal static global::System.Resources.ResourceManager ResourceManager
- {
- get
- {
- if (object.ReferenceEquals(resourceMan, null))
- {
+ internal static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ASCOM.MeadeAutostar497.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
-
+
///
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
///
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
- internal static global::System.Globalization.CultureInfo Culture
- {
- get
- {
+ internal static global::System.Globalization.CultureInfo Culture {
+ get {
return resourceCulture;
}
- set
- {
+ set {
resourceCulture = value;
}
}
-
+
///
/// Looks up a localized resource of type System.Drawing.Bitmap.
///
- internal static System.Drawing.Bitmap ASCOM
- {
- get
- {
+ internal static System.Drawing.Bitmap ASCOM {
+ get {
object obj = ResourceManager.GetObject("ASCOM", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
-
+
///
/// Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
///
- internal static System.Drawing.Icon DefaultIcon
- {
- get
- {
+ internal static System.Drawing.Icon DefaultIcon {
+ get {
object obj = ResourceManager.GetObject("DefaultIcon", resourceCulture);
return ((System.Drawing.Icon)(obj));
}
diff --git a/MeadeAutostar497/Properties/Settings.Designer.cs b/MeadeAutostar497/Properties/Settings.Designer.cs
index 4e629ed..a2bb372 100644
--- a/MeadeAutostar497/Properties/Settings.Designer.cs
+++ b/MeadeAutostar497/Properties/Settings.Designer.cs
@@ -1,28 +1,24 @@
//------------------------------------------------------------------------------
//
// This code was generated by a tool.
-// Runtime Version:4.0.30319.18052
+// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
//
//------------------------------------------------------------------------------
-namespace ASCOM.MeadeAutostar497.Properties
-{
-
-
+namespace ASCOM.MeadeAutostar497.Properties {
+
+
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")]
- internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
- {
-
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.9.0.0")]
+ internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
+
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
-
- public static Settings Default
- {
- get
- {
+
+ public static Settings Default {
+ get {
return defaultInstance;
}
}
diff --git a/MeadeAutostar497/StringExtensions.cs b/MeadeAutostar497/StringExtensions.cs
new file mode 100644
index 0000000..e6a2cd1
--- /dev/null
+++ b/MeadeAutostar497/StringExtensions.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ASCOM.MeadeAutostar497
+{
+ public static class StringExtensions
+ {
+ public static int ToInteger(this string str)
+ {
+ return int.Parse(str);
+ }
+ }
+}
diff --git a/MeadeAutostar497/app.config b/MeadeAutostar497/app.config
index e4eb090..dd30df1 100644
--- a/MeadeAutostar497/app.config
+++ b/MeadeAutostar497/app.config
@@ -5,4 +5,4 @@
-
+
diff --git a/TargetToBeat.txt b/TargetToBeat.txt
new file mode 100644
index 0000000..8255bd9
--- /dev/null
+++ b/TargetToBeat.txt
@@ -0,0 +1,249 @@
+
+ConformanceCheck ASCOM Device Conformance Checker Version 6.4.63.0, Build time: 18/12/2018 08:58:34
+ConformanceCheck Running on: ASCOM Platform 6.4 SP1 6.4.1.2695
+
+ConformanceCheck Driver ProgID: MeadeEx.Telescope
+
+Error handling
+Error number for "Not Implemented" is: 80040400
+Error number for "Invalid Value 1" is: 80040401
+Error number for "Invalid Value 2" is: 80040405
+Error number for "Value Not Set 1" is: 80040402
+Error number for "Value Not Set 2" is: 80040403
+Error messages will not be interpreted to infer state.
+
+21:04:42.255 Driver Access Checks OK
+21:04:42.997 AccessChecks OK Successfully created driver using late binding
+21:04:50.059 AccessChecks OK Successfully connected using late binding
+21:04:50.063 AccessChecks INFO The driver is a COM object
+21:04:57.769 AccessChecks INFO Device exposes interface ITelescopeV2
+21:04:58.546 AccessChecks INFO Device does not expose interface ITelescopeV3
+21:04:59.881 AccessChecks OK Successfully created driver using driver access toolkit
+21:05:06.873 AccessChecks OK Successfully connected using driver access toolkit
+
+Conform is using ASCOM.DriverAccess.Telescope to get a Telescope object
+21:05:08.261 ConformanceCheck OK Driver instance created successfully
+21:05:15.293 ConformanceCheck OK Connected OK
+
+Common Driver Methods
+21:05:15.333 InterfaceVersion OK 2
+21:05:15.362 Connected OK True
+21:05:15.448 Description OK Meade Autostar 497: ETX Autostar|A|43Ea|Jun 02 2006@10:09:40
+21:05:15.480 DriverInfo OK ASCOM Meade Telescope/Focuser driver for classic and Autostar I 5.0.4
+ ASCOM Iniative
+ http://ascom-standards.org/
+ Last Modified 10/06/2013 19:06:54
+21:05:15.509 DriverVersion OK 5.0
+21:05:15.539 Name OK Autostar 497
+21:05:15.568 CommandString INFO Conform cannot test the CommandString method
+21:05:15.572 CommandBlind INFO Conform cannot test the CommandBlind method
+21:05:15.582 CommandBool INFO Conform cannot test the CommandBool method
+21:05:15.588 Action INFO Conform cannot test the Action method
+21:05:15.595 SupportedActions OK Driver returned an empty action list
+
+Can Properties
+21:05:15.663 CanFindHome OK False
+21:05:15.671 CanPark OK True
+21:05:15.679 CanPulseGuide OK True
+21:05:15.687 CanSetDeclinationRate OK False
+21:05:15.695 CanSetGuideRates OK False
+21:05:15.703 CanSetPark OK False
+21:05:15.711 CanSetPierSide OK False
+21:05:15.719 CanSetRightAscensionRate OK False
+21:05:15.727 CanSetTracking OK False
+21:05:15.735 CanSlew OK True
+21:05:15.743 CanSlewltAz OK True
+21:05:15.752 CanSlewAltAzAsync OK True
+21:05:15.761 CanSlewAsync OK True
+21:05:15.769 CanSync OK True
+21:05:15.777 CanSyncAltAz OK False
+21:05:15.785 CanUnPark OK False
+
+Pre-run Checks
+21:05:15.834 Mount Safety INFO Scope is not parked, continuing testing
+21:05:15.887 TimeCheck INFO PC Time Zone: GMT Summer Time, offset -1 hours.
+21:05:15.894 TimeCheck INFO PC UTCDate: 30-Apr-2019 20:05:15.894
+21:05:16.013 TimeCheck INFO Mount UTCDate: 30-Apr-2019 20:04:15.000
+
+Properties
+21:05:16.063 AlignmentMode OK algPolar
+21:05:16.117 Altitude OK 90.00
+21:05:16.149 ApertureArea ERROR Unexpected DriverAccessCOMException, : Property ApertureAreaThe supplied value is out of range for this property.
+21:05:16.182 ApertureDiameter ERROR Unexpected DriverAccessCOMException, : Property ApertureDiameterThe supplied value is out of range for this property.
+21:05:16.214 AtHome OK False
+21:05:16.245 AtPark OK False
+21:05:16.310 Azimuth OK 0.57
+21:05:16.369 Declination OK 89:59:59.00
+21:05:16.402 DeclinationRate Read OK 0.00
+21:05:16.434 DeclinationRate Write OK CanSetDeclinationRate is False and a PropertyNotImplementedException exception was generated as expected
+21:05:16.469 DoesRefraction Read OK True
+21:05:16.501 DoesRefraction Write ERROR Unexpected DriverAccessCOMException, : Property DoesRefractionThe supplied value is out of range for this property.
+21:05:16.534 EquatorialSystem OK equLocalTopocentric
+21:05:16.568 FocalLength ERROR Unexpected DriverAccessCOMException, : Property FocalLengthThe supplied value is out of range for this property.
+21:05:16.602 GuideRateDeclination Read OK 0.00
+21:05:16.613 GuideRateDeclination Write OK CanSetGuideRates is False and a PropertyNotImplementedException exception was generated as expected
+21:05:16.646 GuideRateRightAscension Read OK 0.00
+21:05:16.661 GuideRateRightAscension Write OK CanSetGuideRates is False and a PropertyNotImplementedException exception was generated as expected
+21:05:16.694 IsPulseGuiding OK False
+21:05:16.748 RightAscension OK 22:28:48.00
+21:05:16.781 RightAscensionRate Read OK 0.00
+21:05:16.814 RightAscensionRate Write OK CanSetRightAscensionRate is False and a PropertyNotImplementedException exception was generated as expected
+21:05:16.848 SiteElevation Read OK 0
+21:05:16.884 SiteElevation Write ERROR Unexpected DriverAccessCOMException, : Property SiteElevation The supplied value is out of range for this property.
+21:05:16.896 SiteElevation Write ERROR Unexpected DriverAccessCOMException, : Property SiteElevation The supplied value is out of range for this property.
+21:05:16.908 SiteElevation Write OK Legal value 0m written successfully
+21:05:16.965 SiteLatitude Read OK 53:50:00.00
+21:05:16.999 SiteLatitude Write OK Optional member threw a PropertyNotImplementedException exception.
+21:05:17.012 SiteLatitude Write OK Optional member threw a PropertyNotImplementedException exception.
+21:05:17.025 SiteLatitude Write OK Optional member threw a PropertyNotImplementedException exception.
+21:05:17.096 SiteLongitude Read OK -01:46:00.00
+21:05:17.130 SiteLongitude Write OK Optional member threw a PropertyNotImplementedException exception.
+21:05:17.144 SiteLongitude Write OK Optional member threw a PropertyNotImplementedException exception.
+21:05:17.156 SiteLongitude Write OK Optional member threw a PropertyNotImplementedException exception.
+21:05:17.192 Slewing OK False
+21:05:17.226 SlewSettleTime Read OK 0
+21:05:17.262 SlewSettleTime Write ERROR Unexpected DriverAccessCOMException, : Property SlewSettleTime The supplied value is out of range for this property.
+21:05:17.277 SlewSettleTime Write OK Legal value 0 seconds written successfully
+21:05:17.313 SideOfPier Read OK Optional member threw a PropertyNotImplementedException exception.
+21:05:17.356 SiderealTime OK 10:31:06.00
+21:05:17.368 SiderealTime OK Scope and ASCOM sidereal times agree to better than 5 minutes, Scope: 10:31:06.00, ASCOM: 10:32:07.97
+21:05:17.405 TargetDeclination Read ERROR Unexpected DriverAccessCOMException, : The target value is not set.
+21:05:17.440 TargetDeclination Write INFO Tests moved after the SlewToCoordinates tests so that Conform can check they properly set target coordinates.
+21:05:17.454 TargetRightAscension Read ERROR Unexpected DriverAccessCOMException, : The target value is not set.
+21:05:17.489 TargetRightAscension Write INFO Tests moved after the SlewToCoordinates tests so that Conform can check they properly set target coordinates.
+21:05:17.502 Tracking Read OK True
+21:05:17.537 Tracking Write OK CanSetTracking is False and a PropertyNotImplementedException exception was generated as expected
+21:05:17.575 TrackingRates ERROR Unexpected System.Reflection.TargetInvocationException exception, : Exception has been thrown by the target of an invocation.
+21:05:17.590 TrackingRates ERROR Unexpected System.Reflection.TargetInvocationException exception, : Exception has been thrown by the target of an invocation.
+21:05:17.603 TrackingRates OK Dispose member not present
+21:05:17.638 TrackingRates OK Successfully obtained a TrackingRates object after the previous TrackingRates object was disposed
+21:05:17.651 TrackingRate Read OK driveSidereal
+21:05:17.665 TrackingRate Write ERROR Unexpected System.Reflection.TargetInvocationException exception, : Exception has been thrown by the target of an invocation.
+21:05:17.760 UTCDate Read OK 30-Apr-2019 20:04:16.000
+21:05:17.774 UTCDate Write OK Optional member threw a PropertyNotImplementedException exception.
+
+Methods
+21:05:17.858 CanMoveAxis:Primary OK CanMoveAxis:Primary False
+21:05:17.894 CanMoveAxis:Secondary OK CanMoveAxis:Secondary False
+21:05:17.931 CanMoveAxis:Tertiary OK CanMoveAxis:Tertiary False
+21:05:17.967 Park/Unpark INFO Tests skipped
+21:05:18.981 AbortSlew OK AbortSlew OK when not slewing
+21:05:19.040 AxisRate:Primary Enum ERROR .NET - Exception: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Runtime.InteropServices.COMException: Member not found. (Exception from HRESULT: 0x80020003 (DISP_E_MEMBERNOTFOUND))
+ --- End of inner exception stack trace ---
+ at Microsoft.VisualBasic.CompilerServices.Symbols.Container.InvokeMethod(Method TargetProcedure, Object[] Arguments, Boolean[] CopyBack, BindingFlags Flags)
+ at Microsoft.VisualBasic.CompilerServices.NewLateBinding.ObjectLateGet(Object Instance, Type Type, String MemberName, Object[] Arguments, String[] ArgumentNames, Type[] TypeArguments, Boolean[] CopyBack)
+ at Microsoft.VisualBasic.CompilerServices.NewLateBinding.LateGet(Object Instance, Type Type, String MemberName, Object[] Arguments, String[] ArgumentNames, Type[] TypeArguments, Boolean[] CopyBack)
+ at Conform.TelescopeTester.TelescopeAxisRateTest(String p_Name, TelescopeAxes p_Axis) in J:\Conform\Conform\Devices\TelescopeTester.vb:line 3022
+21:05:19.055 AxisRate:Primary OK Empty axis rate returned
+21:05:19.069 AxisRate:Primary OK AxisRates.Dispose() member not present for axis axisPrimary
+21:05:19.085 AxisRate:Secondary Enum ERROR .NET - Exception: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Runtime.InteropServices.COMException: Member not found. (Exception from HRESULT: 0x80020003 (DISP_E_MEMBERNOTFOUND))
+ --- End of inner exception stack trace ---
+ at Microsoft.VisualBasic.CompilerServices.Symbols.Container.InvokeMethod(Method TargetProcedure, Object[] Arguments, Boolean[] CopyBack, BindingFlags Flags)
+ at Microsoft.VisualBasic.CompilerServices.NewLateBinding.ObjectLateGet(Object Instance, Type Type, String MemberName, Object[] Arguments, String[] ArgumentNames, Type[] TypeArguments, Boolean[] CopyBack)
+ at Microsoft.VisualBasic.CompilerServices.NewLateBinding.LateGet(Object Instance, Type Type, String MemberName, Object[] Arguments, String[] ArgumentNames, Type[] TypeArguments, Boolean[] CopyBack)
+ at Conform.TelescopeTester.TelescopeAxisRateTest(String p_Name, TelescopeAxes p_Axis) in J:\Conform\Conform\Devices\TelescopeTester.vb:line 3022
+21:05:19.100 AxisRate:Secondary OK Empty axis rate returned
+21:05:19.117 AxisRate:Secondary OK AxisRates.Dispose() member not present for axis axisSecondary
+21:05:19.132 AxisRate:Tertiary Enum ERROR .NET - Exception: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Runtime.InteropServices.COMException: Member not found. (Exception from HRESULT: 0x80020003 (DISP_E_MEMBERNOTFOUND))
+ --- End of inner exception stack trace ---
+ at Microsoft.VisualBasic.CompilerServices.Symbols.Container.InvokeMethod(Method TargetProcedure, Object[] Arguments, Boolean[] CopyBack, BindingFlags Flags)
+ at Microsoft.VisualBasic.CompilerServices.NewLateBinding.ObjectLateGet(Object Instance, Type Type, String MemberName, Object[] Arguments, String[] ArgumentNames, Type[] TypeArguments, Boolean[] CopyBack)
+ at Microsoft.VisualBasic.CompilerServices.NewLateBinding.LateGet(Object Instance, Type Type, String MemberName, Object[] Arguments, String[] ArgumentNames, Type[] TypeArguments, Boolean[] CopyBack)
+ at Conform.TelescopeTester.TelescopeAxisRateTest(String p_Name, TelescopeAxes p_Axis) in J:\Conform\Conform\Devices\TelescopeTester.vb:line 3022
+21:05:19.149 AxisRate:Tertiary OK Empty axis rate returned
+21:05:19.178 AxisRate:Tertiary OK AxisRates.Dispose() member not present for axis axisTertiary
+21:05:19.195 FindHome OK CanFindHome is False and a MethodNotImplementedException exception was generated as expected
+21:05:19.234 MoveAxis Primary OK CanMoveAxis Primary is False and a MethodNotImplementedException exception was generated as expected
+21:05:19.273 MoveAxis Secondary OK CanMoveAxis Secondary is False and a MethodNotImplementedException exception was generated as expected
+21:05:19.314 MoveAxis Tertiary OK CanMoveAxis Tertiary is False and a MethodNotImplementedException exception was generated as expected
+21:05:21.349 PulseGuide OK Synchronous pulse guide found OK
+21:06:13.942 SlewToCoordinates INFO Slewed within 15.0 arc seconds of expected RA: 09:31:10.00, actual RA: 09:31:09.00
+21:06:13.956 SlewToCoordinates OK Slewed OK. DEC: 01:00:00.00
+21:06:13.971 SlewToCoordinates OK The TargetRightAscension property 09:31:10.00 matches the expected RA OK.
+21:06:13.987 SlewToCoordinates OK The TargetDeclination property 01:00:00.00 matches the expected Declination OK.
+21:06:14.028 SlewToCoordinates (Bad L) ERROR Unexpected DriverAccessCOMException, slewing to bad RA coordinate: Property TargetRightAscension The supplied value is out of range for this property.
+21:06:14.102 SlewToCoordinates (Bad L) ERROR Unexpected DriverAccessCOMException, slewing to bad Dec coordinate: Property TargetDeclination The supplied value is out of range for this property.
+21:06:14.164 SlewToCoordinates (Bad H) ERROR Unexpected DriverAccessCOMException, slewing to bad RA coordinate: Property TargetRightAscension The supplied value is out of range for this property.
+21:06:14.262 SlewToCoordinates (Bad H) ERROR Unexpected DriverAccessCOMException, slewing to bad Dec coordinate: Property TargetDeclination The supplied value is out of range for this property.
+21:06:48.075 SlewToCoordinatesAsync INFO Slewed within 45.0 arc seconds of expected RA: 08:32:03.00, actual RA: 08:32:00.00
+21:06:48.090 SlewToCoordinatesAsync OK Slewed OK. DEC: 02:00:00.00
+21:06:48.106 SlewToCoordinatesAsync OK The TargetRightAscension property 08:32:03.00 matches the expected RA OK.
+21:06:48.122 SlewToCoordinatesAsync OK The TargetDeclination property 02:00:00.00 matches the expected Declination OK.
+21:06:48.164 SlewToCoordinatesAsync (Bad L) ERROR Unexpected DriverAccessCOMException, slewing to bad RA coordinate: Property TargetRightAscension The supplied value is out of range for this property.
+21:06:48.239 SlewToCoordinatesAsync (Bad L) ERROR Unexpected DriverAccessCOMException, slewing to bad Dec coordinate: Property TargetDeclination The supplied value is out of range for this property.
+21:06:48.302 SlewToCoordinatesAsync (Bad H) ERROR Unexpected DriverAccessCOMException, slewing to bad RA coordinate: Property TargetRightAscension The supplied value is out of range for this property.
+21:06:48.436 SlewToCoordinatesAsync (Bad H) ERROR Unexpected DriverAccessCOMException, slewing to bad Dec coordinate: Property TargetDeclination The supplied value is out of range for this property.
+21:07:22.044 SyncToCoordinates INFO Slewed to start position within 15.0 arc seconds of expected RA: 07:32:37.00, actual RA: 07:32:36.00
+21:07:22.061 SyncToCoordinates OK Slewed to start position OK. DEC: 26:55:00.00
+21:07:22.782 SyncToCoordinates INFO Synced to sync position within 15.0 arc seconds of expected RA: 07:28:37.00, actual RA: 07:28:36.00
+21:07:22.796 SyncToCoordinates OK Synced to sync position OK. DEC: 25:55:00.00
+21:07:22.812 SyncToCoordinates OK The TargetRightAscension property 07:28:37.00 matches the expected RA OK.
+21:07:22.828 SyncToCoordinates OK The TargetDeclination property 25:55:00.00 matches the expected Declination OK.
+21:07:53.961 SyncToCoordinates INFO Slewed back to start position within 15.0 arc seconds of expected RA: 07:32:37.00, actual RA: 07:32:36.00
+21:07:53.976 SyncToCoordinates OK Slewed back to start position OK. DEC: 26:55:00.00
+21:07:54.692 SyncToCoordinates INFO Synced to reversed sync position within 30.0 arc seconds of expected RA: 07:36:37.00, actual RA: 07:36:35.00
+21:07:54.708 SyncToCoordinates OK Synced to reversed sync position OK. DEC: 27:55:00.00
+21:08:25.954 SyncToCoordinates INFO Slewed back to start position within 15.0 arc seconds of expected RA: 07:32:37.00, actual RA: 07:32:36.00
+21:08:25.969 SyncToCoordinates OK Slewed back to start position OK. DEC: 26:55:00.00
+21:08:26.009 SyncToCoordinates (Bad L) ERROR Unexpected DriverAccessCOMException, syncing to bad RA coordinate: Property TargetRightAscension The supplied value is out of range for this property.
+21:08:26.087 SyncToCoordinates (Bad L) ERROR Unexpected DriverAccessCOMException, syncing to bad Dec coordinate: Property TargetDeclination The supplied value is out of range for this property.
+21:08:26.150 SyncToCoordinates (Bad H) ERROR Unexpected DriverAccessCOMException, syncing to bad RA coordinate: Property TargetRightAscension The supplied value is out of range for this property.
+21:08:26.229 SyncToCoordinates (Bad H) ERROR Unexpected DriverAccessCOMException, syncing to bad Dec coordinate: Property TargetDeclination The supplied value is out of range for this property.
+21:08:26.292 TargetRightAscension Write ERROR Unexpected DriverAccessCOMException, : Property TargetRightAscension The supplied value is out of range for this property.
+21:08:26.311 TargetRightAscension Write ERROR Unexpected DriverAccessCOMException, : Property TargetRightAscension The supplied value is out of range for this property.
+21:08:26.395 TargetRightAscension Write OK Legal value 06:34:15.00 HH:MM:SS written successfully
+21:08:26.435 TargetDeclination Write ERROR Unexpected DriverAccessCOMException, : Property TargetDeclination The supplied value is out of range for this property.
+21:08:26.454 TargetDeclination Write ERROR Unexpected DriverAccessCOMException, : Property TargetDeclination The supplied value is out of range for this property.
+21:08:26.506 TargetDeclination Write OK Legal value 01:00:00.00 DD:MM:SS written successfully
+21:08:57.865 SlewToTarget INFO Slewed within 45.0 arc seconds of expected RA: 07:34:15.00, actual RA: 07:34:12.00
+21:08:57.880 SlewToTarget OK Slewed OK. DEC: 03:00:00.00
+21:08:57.897 SlewToTarget OK The TargetRightAscension property 07:34:15.00 matches the expected RA OK.
+21:08:57.915 SlewToTarget OK The TargetDeclination property 03:00:00.00 matches the expected Declination OK.
+21:08:57.959 SlewToTarget (Bad L) ERROR Unexpected DriverAccessCOMException, Exception setting bad RA coordinate: Property TargetRightAscension The supplied value is out of range for this property.
+21:08:58.003 SlewToTarget (Bad L) ERROR Unexpected DriverAccessCOMException, Exception setting bad Dec coordinate: Property TargetDeclination The supplied value is out of range for this property.
+21:08:58.064 SlewToTarget (Bad H) ERROR Unexpected DriverAccessCOMException, Exception setting bad RA coordinate: Property TargetRightAscension The supplied value is out of range for this property.
+21:08:58.114 SlewToTarget (Bad H) ERROR Unexpected DriverAccessCOMException, Exception setting bad Dec coordinate: Property TargetDeclination The supplied value is out of range for this property.
+21:09:29.948 SlewToTargetAsync INFO Slewed within 45.0 arc seconds of expected RA: 06:34:47.00, actual RA: 06:34:44.00
+21:09:29.964 SlewToTargetAsync OK Slewed OK. DEC: 04:00:00.00
+21:09:29.979 SlewToTargetAsync OK The TargetRightAscension property 06:34:47.00 matches the expected RA OK.
+21:09:29.996 SlewToTargetAsync OK The TargetDeclination property 04:00:00.00 matches the expected Declination OK.
+21:09:30.038 SlewToTargetAsync (Bad L) ERROR Unexpected DriverAccessCOMException, Exception setting bad RA coordinate: Property TargetRightAscension The supplied value is out of range for this property.
+21:09:30.085 SlewToTargetAsync (Bad L) ERROR Unexpected DriverAccessCOMException, Exception setting bad Dec coordinate: Property TargetDeclination The supplied value is out of range for this property.
+21:09:30.150 SlewToTargetAsync (Bad H) ERROR Unexpected DriverAccessCOMException, Exception setting bad RA coordinate: Property TargetRightAscension The supplied value is out of range for this property.
+21:09:30.196 SlewToTargetAsync (Bad H) ERROR Unexpected DriverAccessCOMException, Exception setting bad Dec coordinate: Property TargetDeclination The supplied value is out of range for this property.
+21:09:30.257 DestinationSideOfPier Test skipped as AligmentMode is not German Polar
+21:09:30.278 SlewToAltAz ERROR Unexpected DriverAccessCOMException, CanSlewAltAz is True: Wrong tracking state
+21:09:30.322 SlewToAltAz (Bad L) ERROR Unexpected DriverAccessCOMException, slewing to bad Altitude coordinate: Wrong tracking state
+21:09:30.343 SlewToAltAz (Bad L) ERROR Unexpected DriverAccessCOMException, slewing to bad Azimuth coordinate: Wrong tracking state
+21:09:30.407 SlewToAltAz (Bad H) ERROR Unexpected DriverAccessCOMException, slewing to bad Altitude coordinate: Wrong tracking state
+21:09:30.426 SlewToAltAz (Bad H) ERROR Unexpected DriverAccessCOMException, slewing to bad Azimuth coordinate: Wrong tracking state
+21:09:30.492 SlewToAltAzAsync ERROR Unexpected DriverAccessCOMException, CanSlewAltAzAsync is True: Wrong tracking state
+21:09:30.534 SlewToAltAzAsync (Bad L) ERROR Unexpected DriverAccessCOMException, slewing to bad Altitude coordinate: Wrong tracking state
+21:09:30.552 SlewToAltAzAsync (Bad L) ERROR Unexpected DriverAccessCOMException, slewing to bad Azimuth coordinate: Wrong tracking state
+21:09:30.617 SlewToAltAzAsync (Bad H) ERROR Unexpected DriverAccessCOMException, slewing to bad Altitude coordinate: Wrong tracking state
+21:09:30.637 SlewToAltAzAsync (Bad H) ERROR Unexpected DriverAccessCOMException, slewing to bad Azimuth coordinate: Wrong tracking state
+21:10:05.974 SyncToTarget OK Slewed to start position OK. RA: 07:35:20.00
+21:10:05.993 SyncToTarget OK Slewed to start position OK. DEC: 26:55:00.00
+21:10:06.721 SyncToTarget OK Synced to sync position OK. RA: 07:31:20.00
+21:10:06.736 SyncToTarget OK Synced to sync position OK. DEC: 25:55:00.00
+21:10:37.626 SyncToTarget OK Slewed back to start position OK. RA: 07:35:20.00
+21:10:37.641 SyncToTarget OK Slewed back to start position OK. DEC: 26:55:00.00
+21:10:38.363 SyncToTarget OK Synced to reversed sync position OK. RA: 07:39:20.00
+21:10:38.381 SyncToTarget OK Synced to reversed sync position OK. DEC: 27:55:00.00
+21:11:09.639 SyncToTarget OK Slewed back to start position OK. RA: 07:35:20.00
+21:11:09.657 SyncToTarget OK Slewed back to start position OK. DEC: 26:55:00.00
+21:11:09.697 SyncToTarget (Bad L) ERROR Unexpected DriverAccessCOMException, Exception setting bad RA coordinate: Property TargetRightAscension The supplied value is out of range for this property.
+21:11:09.741 SyncToTarget (Bad L) ERROR Unexpected DriverAccessCOMException, Exception setting bad Dec coordinate: Property TargetDeclination The supplied value is out of range for this property.
+21:11:09.803 SyncToTarget (Bad H) ERROR Unexpected DriverAccessCOMException, Exception setting bad RA coordinate: Property TargetRightAscension The supplied value is out of range for this property.
+21:11:09.847 SyncToTarget (Bad H) ERROR Unexpected DriverAccessCOMException, Exception setting bad Dec coordinate: Property TargetDeclination The supplied value is out of range for this property.
+21:11:10.010 SyncToAltAz OK CanSyncAltAz is False and a MethodNotImplementedException exception was generated as expected
+
+SideOfPier Model Tests
+21:11:10.080 SideOfPier Model Tests INFO Tests skipped because this driver does Not support SideOfPier Read
+
+Post-run Checks
+21:11:10.180 Mount Safety INFO Tracking can't be turned off for this mount, please switch off manually.
+
+Conformance test complete
+
+Your driver had 53 errors, 0 warnings and 0 issues
\ No newline at end of file
diff --git a/TestConsole/Program.cs b/TestConsole/Program.cs
new file mode 100644
index 0000000..6c8fa71
--- /dev/null
+++ b/TestConsole/Program.cs
@@ -0,0 +1,73 @@
+// This implements a console application that can be used to test an ASCOM driver
+//
+
+// This is used to define code in the template that is specific to one class implementation
+// unused code can be deleted and this definition removed.
+
+#define Telescope
+// remove this to bypass the code that uses the chooser to select the driver
+#define UseChooser
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace ASCOM
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ // Uncomment the code that's required
+#if UseChooser
+ // choose the device
+ string id = ASCOM.DriverAccess.Telescope.Choose("ASCOM.MeadeAutostar497.Telescope");
+ if (string.IsNullOrEmpty(id))
+ return;
+ // create this device
+ ASCOM.DriverAccess.Telescope device = new ASCOM.DriverAccess.Telescope(id);
+#else
+ // this can be replaced by this code, it avoids the chooser and creates the driver class directly.
+ ASCOM.DriverAccess.Telescope device = new ASCOM.DriverAccess.Telescope("ASCOM.MeadeAutostar497.Telescope");
+#endif
+ // now run some tests, adding code to your driver so that the tests will pass.
+ // these first tests are common to all drivers.
+ Console.WriteLine("name " + device.Name);
+ Console.WriteLine("description " + device.Description);
+ Console.WriteLine("DriverInfo " + device.DriverInfo);
+ Console.WriteLine("driverVersion " + device.DriverVersion);
+
+ // TODO add more code to test the driver.
+ device.Connected = true;
+
+ //Console.WriteLine(device.Slewing);
+
+ //device.UTCDate = DateTime.UtcNow;
+ //Console.WriteLine(device.UTCDate.ToLocalTime());
+
+
+ //Console.WriteLine(device.AlignmentMode);
+
+
+
+ //double l = device.SiteLatitude;
+ //device.SiteLatitude = l;
+
+ //double l = device.SiteLongitude;
+ //device.SiteLongitude = l;
+ //Console.WriteLine(device.SiteLongitude);
+
+ //Console.WriteLine(device.RightAscension);
+
+ //device.SlewToAltAz(0,0);
+
+
+ Console.WriteLine(device.TrackingRate);
+
+ device.Connected = false;
+ Console.WriteLine("Press Enter to finish");
+ Console.ReadLine();
+ }
+ }
+}
diff --git a/TestConsole/Properties/AssemblyInfo.cs b/TestConsole/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..86599a1
--- /dev/null
+++ b/TestConsole/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("q Test Application")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("ASCOM Initiative")]
+[assembly: AssemblyProduct("q")]
+[assembly: AssemblyCopyright("Copyright © ASCOM Initiative 2014")]
+[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("c7008f94-e3b9-4481-b720-3b56557860c6")]
+
+// 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("6.4.0.0")]
+[assembly: AssemblyFileVersion("6.4.0.0")]
diff --git a/TestConsole/TestConsole.csproj b/TestConsole/TestConsole.csproj
new file mode 100644
index 0000000..4392996
--- /dev/null
+++ b/TestConsole/TestConsole.csproj
@@ -0,0 +1,64 @@
+
+
+
+ Debug
+ x86
+ 8.0.30703
+ 2.0
+ {D5207217-61C7-4E94-8097-91DBACE57D2A}
+ Exe
+ Properties
+ TestConsole
+ TestConsole
+ v4.6
+
+
+ 512
+
+
+ x64
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+ false
+
+
+ x86
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/TestConsole/app.config b/TestConsole/app.config
new file mode 100644
index 0000000..8935d57
--- /dev/null
+++ b/TestConsole/app.config
@@ -0,0 +1,3 @@
+
+
+