diff --git a/.gitignore b/.gitignore
index 5f43b23a..53734d2f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -265,3 +265,17 @@ AWSConstants.cs
/ControlRoomApplication/ControlRoomApplication/Constants/AWSConstants.cs
/ControlRoomApplication/results.xml
/ControlRoomApplication/ControlRoomApplication.dll
+
+# Not an AES key or IV so don't look here
+/ControlRoomApplication/ControlRoomApplication/Constants/AESConstants.cs
+
+# Sensitive push notification data
+/ControlRoomApplication/ControlRoomApplication/Controllers/Communications/pushNotification.cs
+\ControlRoomApplication\ControlRoom\Application\Controllers\Communications\pushNotification.cs
+/ControlRoomApplication/ControlRoomApplication/Controllers/Communications/EmailPartConstants.cs
+\ControlRoomApplication\ControlRoom\Application\Controllers\Communications\EmailPartConstants.cs
+
+
+# Gradle stuff
+/.gradle
+ControlRoomApplication/ControlRoomApplicationTest/ControlRoomApplicationTest.csproj
diff --git a/ControlRoomApplication/.editorconfig b/ControlRoomApplication/.editorconfig
new file mode 100644
index 00000000..8f0432e4
--- /dev/null
+++ b/ControlRoomApplication/.editorconfig
@@ -0,0 +1,4 @@
+[*.cs]
+
+# CS1591: Missing XML comment for publicly visible type or member
+dotnet_diagnostic.CS1591.severity = none
diff --git a/ControlRoomApplication/ControlRoomApplication.sln b/ControlRoomApplication/ControlRoomApplication.sln
index 0375bbdf..a91e783a 100644
--- a/ControlRoomApplication/ControlRoomApplication.sln
+++ b/ControlRoomApplication/ControlRoomApplication.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 15
-VisualStudioVersion = 15.0.28010.2016
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.31624.102
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ControlRoomApplication", "ControlRoomApplication\ControlRoomApplication.csproj", "{A9AF6C2B-B653-48AC-8DAD-791197740034}"
EndProject
diff --git a/ControlRoomApplication/ControlRoomApplication/App.config b/ControlRoomApplication/ControlRoomApplication/App.config
index 61ecdbd3..f9f96b61 100644
--- a/ControlRoomApplication/ControlRoomApplication/App.config
+++ b/ControlRoomApplication/ControlRoomApplication/App.config
@@ -38,7 +38,7 @@
-
+
@@ -114,6 +114,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ControlRoomApplication/ControlRoomApplication/Constants/AbstractSpectraCyberConstants.cs b/ControlRoomApplication/ControlRoomApplication/Constants/AbstractSpectraCyberConstants.cs
index bbae65f2..843cc821 100644
--- a/ControlRoomApplication/ControlRoomApplication/Constants/AbstractSpectraCyberConstants.cs
+++ b/ControlRoomApplication/ControlRoomApplication/Constants/AbstractSpectraCyberConstants.cs
@@ -10,7 +10,7 @@ public sealed class AbstractSpectraCyberConstants
public const StopBits STOP_BITS = StopBits.One;
public const int BUFFER_SIZE = 4;
public const int TIMEOUT_MS = 1000;
- public const int WAIT_TIME_MS = 70; // TODO: confirm that this is enough time to wait
+ public const int WAIT_TIME_MS = 70;
public const bool CLIP_BUFFER_RESPONSE = true;
public const string DEFAULT_COMM_PORT = "COM5";
diff --git a/ControlRoomApplication/ControlRoomApplication/Constants/MCUConstants.cs b/ControlRoomApplication/ControlRoomApplication/Constants/MCUConstants.cs
index 95b11a95..ffb5f075 100644
--- a/ControlRoomApplication/ControlRoomApplication/Constants/MCUConstants.cs
+++ b/ControlRoomApplication/ControlRoomApplication/Constants/MCUConstants.cs
@@ -1,11 +1,9 @@
-namespace ControlRoomApplication.Constants
-{
- public sealed class MCUConstants
- {
+namespace ControlRoomApplication.Constants {
+ public sealed class MCUConstants {
public const double SIMULATION_MCU_PEAK_VELOCITY = 22.5; // steps/s
public const double SIMULATION_MCU_PEAK_ACCELERATION = 32.0; // steps/s^2
- public const int ACTUAL_MCU_DEFAULT_PEAK_VELOCITY = 500000; // steps/s
+ public const int ACTUAL_MCU_DEFAULT_PEAK_VELOCITY = 500_000; // steps/s
public const int ACTUAL_MCU_DEFAULT_ACCELERATION = 1000; // steps/ms/s
public const double ACTUAL_MCU_STEPS_PER_DEGREE = 166 + (2.0 / 3);
@@ -16,7 +14,235 @@ public sealed class MCUConstants
public const ushort ACTUAL_MCU_READ_INPUT_REGISTER_CURRENT_POSITION_ADDRESS = 2;
public const ushort ACTUAL_MCU_WRITE_REGISTER_START_ADDRESS = 1024;
public const int ACTUAL_MCU_AZIMUTH_ENCODER_BIT_RESOLUTION = 12;
- public const int ACTUAL_MCU_MOVE_PEAK_VELOCITY_WITH_GEARING = 100000;
+ public const int ACTUAL_MCU_MOVE_PEAK_VELOCITY_WITH_GEARING = 100_000;
public const ushort ACTUAL_MCU_MOVE_ACCELERATION_WITH_GEARING = 50;
+
+
+ ///
+ /// this enum represents the data that comes out of the MCU starting in position = 0 of its registers
+ ///
+ public enum MCUOutputRegs : ushort {
+ ///
+ /// most signifigant word (16 bits) of the az axsys status for description of eacs bit
+ ///
+ AZ_Status_Bist_MSW = 0,
+ ///
+ /// least signifigant word (16 bits) of the az axsys status for description of eacs bit
+ ///
+ AZ_Status_Bist_LSW = 1,
+ ///
+ /// this is the position of the axsys in terms of motor step count (most signifigant word)
+ ///
+ AZ_Current_Position_MSW = 2,
+ ///
+ /// this is the position of the axsys in terms of motor step count (least signifigant word)
+ ///
+ AZ_Current_Position_LSW = 3,
+ ///
+ /// if we were using encoders on the motors this is where the data from those encoders would be
+ ///
+ AZ_MTR_Encoder_Pos_MSW=4,
+ ///
+ /// if we were using encoders on the motors this is where the data from those encoders would be
+ ///
+ AZ_MTR_Encoder_Pos_LSW = 5,
+ ///
+ /// if the MCU is told to capture the current position this is where that data will be stored
+ ///
+ AZ_Capture_Data_MSW=6,
+ ///
+ /// if the MCU is told to capture the current position this is where that data will be stored
+ ///
+ AZ_Capture_Data_LSW = 7,
+ RESERVED1 =8,
+ ///
+ /// used to track network conectivity bit 14 of this register will flip every .5 seconds,
+ /// bit 13 is set when the MCU looses or has previously lost ethernet conectivity
+ ///
+ NetworkConnectivity = 9,
+ ///
+ /// most signifigant word (16 bits) of the EL axsys status for description of eacs bit
+ ///
+ EL_Status_Bist_MSW = 10,
+ ///
+ /// least signifigant word (16 bits) of the EL axsys status for description of eacs bit
+ ///
+ EL_Status_Bist_LSW = 11,
+ ///
+ /// this is the position of the axsys in terms of motor step count (most signifigant word)
+ ///
+ EL_Current_Position_MSW = 12,
+ ///
+ /// this is the position of the axsys in terms of motor step count (least signifigant word)
+ ///
+ EL_Current_Position_LSW = 13,
+ ///
+ /// if we were using encoders on the motors this is where the data from those encoders would be
+ ///
+ EL_MTR_Encoder_Pos_MSW = 14,
+ ///
+ /// if we were using encoders on the motors this is where the data from those encoders would be
+ ///
+ EL_MTR_Encoder_Pos_LSW = 15,
+ ///
+ /// if the MCU is told to capture the current position this is where that data will be stored
+ ///
+ EL_Capture_Data_MSW = 16,
+ ///
+ /// if the MCU is told to capture the current position this is where that data will be stored
+ ///
+ EL_Capture_Data_LSW = 17,
+ RESERVED2 = 18,
+ RESERVED3 = 19
+
+ }
+
+
+
+ ///
+ /// desciptions taken from anf1-anf2-motion-controller-user-manual.pdf page 76 - 78
+ ///
+ public enum MCUStatusBitsMSW : int {
+ ///
+ /// Set when the ANF1/2 axis is outputting pulses for clockwise motion
+ ///
+ CW_Motion = 0,
+ ///
+ /// Set when the ANF1/2 axis is outputting pulses for counter-clockwise motion
+ ///
+ CCW_Motion = 1,
+ ///
+ /// Set when the ANF1/2 axis has stopped motion as a result of a Hold Move Command
+ ///
+ Hold_State = 2,
+ ///
+ /// Set when the ANF1/2 axis is not in motion for any reason
+ ///
+ Axis_Stopped = 3,
+ ///
+ /// This bit is only set after the successful completion of a homing command
+ ///
+ At_Home = 4,
+ ///
+ /// Set when the ANF1/2 axis is accelerating during any move
+ ///
+ Move_Accelerating = 5,
+ ///
+ /// Set when the ANF1/2 axis is decelerating during any move
+ ///
+ Move_Decelerating = 6,
+ ///
+ /// Set when the ANF1/2 axis has successfully completed an Absolute, Relative,
+ /// Blend, or Interpolated Move
+ ///
+ Move_Complete = 7,
+ ///
+ /// Set when the ANF1/2 could not home the axis because of an error durring homeing see MCU documaentation for list of potential eroorrs
+ ///
+ Home_Invalid_Error = 8,
+ ///
+ /// Set when there was an error in the last Program Blend Profile data block //we don't use blend move so this shouldnt come up
+ ///
+ Profile_Invalid = 9,
+ ///
+ /// this bit is set when the position stored in the MCU could be incorrect.
+ /// set under the fowling conditions, Axis switched to Command Mode | An Immediate Stop command was issued | An Emergency Stop input was activated | CW or CCW Limit reached
+ ///
+ Position_Invalid = 10,
+ ///
+ /// see MCU documaentation for list of potential eroorrs
+ ///
+ Input_Error = 11,
+ ///
+ /// Set when the last command issued to the ANF1/2 axis forced an error
+ ///
+ Command_Error = 12,
+ ///
+ /// set when the axis has a configuration error
+ ///
+ Configuration_Error = 13,
+ ///
+ /// Set when the axis is enabled. Axis 2 of an ANF2 is disabled by default. An
+ /// axis is automatically enabled when valid configuration data is written to it
+ ///
+ Axis_Enabled = 14,
+ ///
+ /// Set to “1” when the axis is in Configuration Mode. Reset to “0” when the axis is in Command Mode
+ ///
+ Axis_Configuration_Mode = 15,
+ }
+
+ ///
+ /// desciptions taken from anf1-anf2-motion-controller-user-manual.pdf page 76 - 78
+ ///
+ public enum MCUStutusBitsLSW : int {
+ ///
+ /// Set when the Capture Input is active
+ ///
+ Capture_Input_Active = 0,
+ ///
+ /// Set when the External Input is active
+ ///
+ External_Input = 1,
+ ///
+ /// Set when the Home Input is active
+ ///
+ Home_Input = 2,
+ ///
+ /// Set when the CW Input/E-Stop Input is active
+ ///
+ CW_Limit = 3,
+ ///
+ /// Set when the CCW Input/E-Stop Input is active
+ ///
+ CCW_Limit = 4,
+ ///
+ /// see MCU documaentation
+ ///
+ No_Fault_Output_State = 5,
+ ///
+ /// see MCU documaentation (unused)
+ ///
+ On_Line_Output_State = 6,
+ ///
+ /// see MCU documaentation (unused)
+ ///
+ Move_Complete_Output_State = 7,
+ ///
+ /// Set when the axis is presently running a Blend Move Profile (unused)
+ ///
+ Running_Blend_Move = 8,
+ ///
+ /// Set when ANF1/2 has accepted a Blend Move Profile programming block (unused)
+ ///
+ Blend_Move_Acknowledge = 9,
+ ///
+ /// Set when the Minimum Registration Move Distance
+ /// parameter is programmed to a non-zero value (unused)
+ ///
+ NonZero_Registration_Distance = 10,
+ ///
+ /// Set when the ANF1/2 is running an Interpolated Move. only valid for axis one
+ ///
+ Running_Interpolated_Move = 11,
+ ///
+ /// This bit always equals the state of the Backplane Home
+ /// Proximity bit, which is bit 6 in the Command Bits LSW for the axis
+ ///
+ Backplane_Home_Proximity = 12,
+ ///
+ /// Set when the axis is in Encoder Follower Mode
+ ///
+ Encoder_Follower_Mode = 13,
+ ///
+ /// These bits will always equal zero
+ ///
+ Reserved1 = 14,
+ ///
+ /// These bits will always equal zero
+ ///
+ reserved2 = 15,
+ }
}
}
+
diff --git a/ControlRoomApplication/ControlRoomApplication/Constants/MiscellaneousConstants.cs b/ControlRoomApplication/ControlRoomApplication/Constants/MiscellaneousConstants.cs
index eedee30f..3f4ee6e3 100644
--- a/ControlRoomApplication/ControlRoomApplication/Constants/MiscellaneousConstants.cs
+++ b/ControlRoomApplication/ControlRoomApplication/Constants/MiscellaneousConstants.cs
@@ -5,11 +5,65 @@ namespace ControlRoomApplication.Constants
public sealed class MiscellaneousConstants
{
public const int MAX_USERNAME_LENGTH = 15;
- public const string LOCAL_DATABASE_NAME = "rtdatabase";
+ public const string LOCAL_DATABASE_NAME = "radio_telescope";
// Can't create const instances, we have to use this as static readonly, sadly
- public static readonly Location JOHN_RUDY_PARK = new Location(76.7046, 40.0244, 395.0);
+ public static readonly Location JOHN_RUDY_PARK = new Location(76.7046, 40.0244, 395.0, "");
public const double NEGLIGIBLE_POSITION_CHANGE_DEGREES = 0.1;
+
+ public static readonly Orientation THERMAL_CALIBRATION_ORIENTATION = new Orientation(200, 20);
+
+ public static readonly double THERMAL_CALIBRATION_OFFSET = 0.01;
+
+ // Software stop elevation thresholds
+
+ ///
+ /// The maximum degree threshold for software stops to stop the telescope
+ ///
+ public const double MAX_SOFTWARE_STOP_EL_DEGREES = 91.0;
+
+ ///
+ /// The minimum degree threshold for software stops to stop the telescope
+ ///
+ public const double MIN_SOFTWARE_STOP_EL_DEGREES = -5.0;
+
+ // constants used for user input validation
+ public const int MAX_PORT_VALUE = 65535;
+
+ public const int MIN_PORT_VALUE = 1; // 0 is reserved!
+
+ public const double MAX_SPEED_RPM = 2.00;
+
+ public const double MIN_SPEED_RPM = 0.00;
+
+ // Constants for orientations that we use in various places
+
+ ///
+ /// The stow position of the telescope. This position has it pointing straight up in the air
+ ///
+ public static readonly Orientation Stow = new Orientation(0, 90);
+
+
+ //constants for acceleration blob
+
+ ///
+ /// The number of acceleration datapoints in one blob to be added to the database
+ ///
+ public const int BLOB_SIZE = 4000;
+
+ // Constant for deleting CSV file attempts
+
+ ///
+ /// This constant is used to represent the maximum number of attempts that are taken to delete the CSV file
+ ///
+ public static readonly int MAX_ATTEMPTS = 9;
+
+
+
+
+
+
+
}
}
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/Constants/MiscellaneousHardwareConstants.cs b/ControlRoomApplication/ControlRoomApplication/Constants/MiscellaneousHardwareConstants.cs
index 8aaba6ad..b6bb4032 100644
--- a/ControlRoomApplication/ControlRoomApplication/Constants/MiscellaneousHardwareConstants.cs
+++ b/ControlRoomApplication/ControlRoomApplication/Constants/MiscellaneousHardwareConstants.cs
@@ -6,8 +6,14 @@ public sealed class MiscellaneousHardwareConstants
public const double LIMIT_SWITCH_EL_THRESHOLD_DEGREES = 2.0;
public const int WEATHER_STATION_DEFAULT_CHECKIN_FREQUENCY_MS = 1000;
+ public const double WEATHER_STATION_WARNING_WIND_SPEED_MPH = 40.0;
public const double WEATHER_STATION_MAXIMUM_ALLOWABLE_WIND_SPEED_MPH = 50.0;
public const double SIMULATION_WEATHER_STATION_AVERAGE_WIND_SPEED_MPH = 20.0;
public const double SIMULATION_WEATHER_STATION_MAXIMUM_ALLOWABLE_WIND_SPEED_MPH_STD_DEV = (WEATHER_STATION_MAXIMUM_ALLOWABLE_WIND_SPEED_MPH - SIMULATION_WEATHER_STATION_AVERAGE_WIND_SPEED_MPH) / 6.0;
+
+ public const int MOVE_BY_X_DEGREES_AZ_MAX = 720;
+
+ public const double SPECTRACYBER_VOLTS_PER_STEP = 0.0024414;
+ public const double SPECTRACYBER_BANDWIDTH_STEP = 5; // Measured in Khz
}
}
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/Constants/MotorConstants.cs b/ControlRoomApplication/ControlRoomApplication/Constants/MotorConstants.cs
index 69ad5b41..4f7d699f 100644
--- a/ControlRoomApplication/ControlRoomApplication/Constants/MotorConstants.cs
+++ b/ControlRoomApplication/ControlRoomApplication/Constants/MotorConstants.cs
@@ -2,7 +2,12 @@
{
public sealed class MotorConstants
{
- public static int STEPS_PER_REVOLUTION_BEFORE_GEARING = 20000;
+ ///
+ /// set by the as a the dip switches on the motordriver default = 20_000
+ ///
+ public static int STEPS_PER_REVOLUTION_BEFORE_GEARING = 20_000;
+
+ public static int ENCODER_COUNTS_PER_REVOLUTION_BEFORE_GEARING = 8000;
public const int GEARING_RATIO_AZIMUTH = 500;
public const int GEARING_RATIO_ELEVATION = 50;
diff --git a/ControlRoomApplication/ControlRoomApplication/Constants/SimulationConstants.cs b/ControlRoomApplication/ControlRoomApplication/Constants/SimulationConstants.cs
new file mode 100644
index 00000000..b8a09a2e
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Constants/SimulationConstants.cs
@@ -0,0 +1,29 @@
+namespace ControlRoomApplication.Constants
+{
+ public sealed class SimulationConstants
+ {
+ public const double STABLE_MOTOR_TEMP = 50; // Measured in fahrenheit
+ public const double OVERHEAT_MOTOR_TEMP = 150;
+ public const double MIN_MOTOR_TEMP = 0;
+ public const double MAX_MOTOR_TEMP = 200;
+
+ public const double AZIMUTH_UPDATE_RATE = 1.0; // Measured as degrees per second
+ public const double ELEVATION_UPDATE_RATE = 0.5;
+ public const double MAX_AZIMUTH_ANGLE = 369; //Measured in degrees
+ public const double MIN_AZIMUTH_ANGLE = -9;
+ public const double MAX_ELEVATION_ANGLE = 94;
+ public const double MIN_ELEVATION_ANGLE = -15;
+
+ public const double LIMIT_CW_AZ_DEGREES = -5;
+ public const double LIMIT_CCW_AZ_DEGREES = 365;
+ public const double LIMIT_LOW_EL_DEGREES = -7; // Changed from -15
+ public const double LIMIT_HIGH_EL_DEGREES = 93; // Changed from 93
+
+ public const double PROX_CW_AZ_DEGREES = 10;
+ public const double PROX_CCW_AZ_DEGREES = 345;
+ public const double PROX_LOW_EL_DEGREES = -5;
+ public const double PROX_HIGH_EL_DEGREES = 85;
+
+
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/Constants/TCPCommunicationConstants.cs b/ControlRoomApplication/ControlRoomApplication/Constants/TCPCommunicationConstants.cs
new file mode 100644
index 00000000..01495116
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Constants/TCPCommunicationConstants.cs
@@ -0,0 +1,101 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ControlRoomApplication.Constants
+{
+ ///
+ /// This class contains all of the error message strings we will be sending back to the mobile app
+ /// or the front-end team while communicating with the control room via RemoteListener.
+ ///
+ public sealed class TCPCommunicationConstants
+ {
+ public static String VERSION_CONVERSION_ERR = "Error converting version from string to double: ";
+
+ public static String VERSION_NOT_FOUND = "The specified version was not found: ";
+
+ public static String AZ_EL_CONVERSION_ERR = "Error converting azimuth or elevation from string to double: ";
+
+ public static String MISSING_AZ_EL_ARGS = "Arguments for AZ or EL not supplied.";
+
+ public static String ORIENTATION_MOVE_ERR = "Command ORIENTATION_MOVE failed with result: ";
+
+ public static String RELATIVE_MOVE_ERR = "Command RELATIVE_MOVE failed with result: ";
+
+ public static String MISSING_OVERRIDE_ARG = "No sensor name supplied for SET_OVERRIDE.";
+
+ public static String MISSING_SET_OVERRIDE_ARG = "No true/false value supplied for SET_OVERRIDE.";
+
+ public static String INVALID_SENSOR_OVERRIDE = "The following sensor was not found to override: ";
+
+ public static String SCRIPT_ERR = "The selected script failed with error: ";
+
+ public static String ALL_STOP_ERR = "The All Stop command failed with error: TimedOut ";
+
+ public static String MISSING_SENSOR_INIT_ARGS = "SENSOR_INIT command is missing arguments; supply all 10 of them. 1" +
+ "means initialize this sensor, 0 means do not initialize.";
+ public static String COMMAND_NOT_FOUND = "The specified command was not found or is invalid: ";
+
+ public static String SCRIPT_NOT_FOUND = "The specified script was not found or is invalid: ";
+
+ public static String MISSING_SCRIPT_TYPE_ARG = "Missing a script name after 'SCRIPT'";
+
+ public static String MISSING_COMMAND_ARGS = "The total number of arguments is invalid for this type of command: ";
+
+ public static String INVALID_REQUEST_TYPE = "The specified REQUEST type was not found or is invalid: ";
+
+ public static String INVALID_VERSION = "This version of TCP does not support this command.";
+
+ public static String[] SCRIPT_NAME_ARRAY = new String[] { "DUMP", "FULL_EV", "THERMAL_CALIBRATE", "STOW", "FULL_CLOCK", "FULL_COUNTER", "HOME", "HARDWARE_MVMT_SCRIPT" };
+
+ public static String[] SENSORS_ARRAY = new String[] { "WEATHER_STATION", "MAIN_GATE", "ELEVATION_LIMIT_0", "ELEVATION_LIMIT_90", "AZ_ABS_ENC", "EL_ABS_ENC", "AZ_ACC", "EL_ACC", "CB_ACC",
+ "AZIMUTH_MOT_TEMP", "ELEVATION_MOT_TEMP" };
+
+ public static String[] ALL_VERSIONS_LIST = new String[] { "1.0", "1.1" };
+
+
+ // Integers for indexing array of command pieces
+ // General numbers
+ public static int VERSION_NUM = 0;
+ public static int COMMAND_TYPE = 1;
+ public static int MIN_NUM_PARAMS = 3; // case of STOP_RT, will only have Version, stopRT, time --> | STOP_RT |
+
+ // Total params expected
+ public static int NUM_SENSOR_OVERRIDE_PARAMS = 5;
+ public static int NUM_SCRIPT_PARAMS = 4;
+ public static int NUM_ORIENTATION_MOVE_PARAMS = 5;
+ public static int NUM_RELATIVE_MOVE_PARAMS = 5;
+ public static int NUM_ALL_STOP_PARAMS = 3;
+ public static int NUM_SENSOR_INIT_PARAMS = 4;
+ public static int NUM_REQUEST_PARAMS = 4;
+ public static int NUM_MCU_RESET_PARAMS = 3;
+
+ // SET_OVERRIDE specific numbers
+ public static int SENSOR_TO_OVERRIDE = 2;
+ public static int DO_OVERRIDE = 3;
+ public static int SENSOR_OVERRIDE_TIME = 4;
+
+ // SCRIPT specific numbers
+ public static int SCRIPT_NAME = 2;
+ public static int SCRIPT_TIME = 3;
+
+ // ORIENTATION_MOVE specific numbers
+ public static int ORIENTATION_MOVE_AZ = 2;
+ public static int ORIENTATION_MOVE_EL = 3;
+ public static int ORIENTATION_MOVE_TIME = 4;
+
+ // RELATIVE_MOVE specific numbers
+ public static int RELATIVE_MOVE_AZ = 2;
+ public static int RELATIVE_MOVE_EL = 3;
+ public static int RELATIVE_MOVE_TIME = 4;
+
+ // REQUEST specific numbers
+ public static int REQUEST_TYPE = 2;
+ public static int REQUEST_TIME = 3;
+
+ // SENSOR_INIT numbers
+ public static int SENSOR_INIT_VALUES = 2;
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/ControlRoomApplication.csproj b/ControlRoomApplication/ControlRoomApplication/ControlRoomApplication.csproj
index aa553691..6c2cd275 100644
--- a/ControlRoomApplication/ControlRoomApplication/ControlRoomApplication.csproj
+++ b/ControlRoomApplication/ControlRoomApplication/ControlRoomApplication.csproj
@@ -16,6 +16,21 @@
true
+ publish\
+ true
+ Disk
+ false
+ Foreground
+ 7
+ Days
+ false
+ false
+ true
+ 0
+ 1.0.0.%2a
+ false
+ false
+ true
AnyCPU
@@ -38,21 +53,35 @@
4
-
-
+ ControlRoomApplication.Main.Program
+
+
+ YCASIcon.ico
-
- ..\packages\AASharp.1.99.1\lib\net45\AASharp.dll
+
+ ..\packages\AASharp.1.93.3\lib\net45\AASharp.dll
+
+
+ ..\packages\ArduinoDriver.2.4.6\lib\net452\ArduinoDriver.dll
+
+
+ ..\packages\ArduinoUploader.3.1.0\lib\net452\ArduinoUploader.dll
- ..\packages\AWSSDK.Core.3.3.103.16\lib\net45\AWSSDK.Core.dll
+ ..\packages\AWSSDK.Core.3.5.1.26\lib\net45\AWSSDK.Core.dll
- ..\packages\AWSSDK.RDS.3.3.107.9\lib\net45\AWSSDK.RDS.dll
+ ..\packages\AWSSDK.RDS.3.5.0\lib\net45\AWSSDK.RDS.dll
-
- ..\packages\BouncyCastle.1.8.3.1\lib\BouncyCastle.Crypto.dll
+
+ ..\packages\AWSSDK.SimpleEmail.3.5.0.28\lib\net45\AWSSDK.SimpleEmail.dll
+
+
+ ..\packages\AWSSDK.SimpleNotificationService.3.5.0\lib\net45\AWSSDK.SimpleNotificationService.dll
+
+
+ ..\packages\BouncyCastle.1.8.9\lib\BouncyCastle.Crypto.dll
..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.dll
@@ -60,26 +89,40 @@
..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.SqlServer.dll
+
+ ..\packages\FftSharp.1.0.8\lib\netstandard2.0\FftSharp.dll
+
..\packages\Google.Protobuf.3.8.0\lib\net45\Google.Protobuf.dll
+
+ ..\packages\IntelHexFormatReader.2.2.3\lib\net46\IntelHexFormatReader.dll
+
..\packages\log4net.2.0.8\lib\net45-full\log4net.dll
+
..\packages\MSTest.TestFramework.1.4.0\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll
..\packages\MSTest.TestFramework.1.4.0\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll
+
+ ..\packages\Microsoft.Win32.Registry.4.3.0\lib\net46\Microsoft.Win32.Registry.dll
+
..\packages\MySql.Data.8.0.17\lib\net452\MySql.Data.dll
..\packages\MySql.Data.EntityFramework.8.0.17\lib\net452\MySql.Data.EntityFramework.dll
+
- ..\packages\Newtonsoft.Json.12.0.2\lib\net45\Newtonsoft.Json.dll
+ ..\packages\Newtonsoft.Json.12.0.1\lib\net45\Newtonsoft.Json.dll
+
+
+ ..\packages\NLog.4.4.10\lib\net45\NLog.dll
..\packages\NModbus4.2.1.0\lib\net40\NModbus4.dll
@@ -87,22 +130,67 @@
..\packages\SSH.NET.2016.1.0\lib\net40\Renci.SshNet.dll
+
+ ..\packages\SerialPortStream.2.1.2\lib\net45\RJCP.SerialPortStream.dll
+
+
+ ..\packages\ScottPlot.4.0.48\lib\netstandard2.0\ScottPlot.dll
+
+
+ ..\packages\ScottPlot.WinForms.4.0.48\lib\net461\ScottPlot.WinForms.dll
+
+
+ ..\packages\System.Collections.NonGeneric.4.3.0\lib\net46\System.Collections.NonGeneric.dll
+ True
+ True
+
+
+ ..\packages\System.Collections.Specialized.4.3.0\lib\net46\System.Collections.Specialized.dll
+
+
+ ..\packages\System.Diagnostics.FileVersionInfo.4.3.0\lib\net46\System.Diagnostics.FileVersionInfo.dll
+
+
+ ..\packages\System.Diagnostics.TraceSource.4.3.0\lib\net46\System.Diagnostics.TraceSource.dll
+
+
+ ..\packages\System.Drawing.Common.4.7.0\lib\net461\System.Drawing.Common.dll
+
+
+ ..\packages\System.IO.FileSystem.4.3.0\lib\net46\System.IO.FileSystem.dll
+
+
+ ..\packages\System.IO.FileSystem.Primitives.4.3.0\lib\net46\System.IO.FileSystem.Primitives.dll
+
+
+ ..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll
+
+
+ ..\packages\System.Threading.Overlapped.4.3.0\lib\net46\System.Threading.Overlapped.dll
+
+
+ ..\packages\System.Threading.Thread.4.3.0\lib\net46\System.Threading.Thread.dll
+
+
+ ..\packages\System.Threading.ThreadPool.4.3.0\lib\net46\System.Threading.ThreadPool.dll
+
..\packages\System.ValueTuple.4.5.0\lib\net461\System.ValueTuple.dll
+
@@ -112,8 +200,11 @@
+
+
+
@@ -124,37 +215,93 @@
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
@@ -185,29 +332,65 @@
+
+
+
+
+
+
+
+ Form
+
+
+ CustomOrientationInputDialog.cs
+
Form
DiagnosticsForm.cs
-
+
+
+ Form
+
+
+ EditTestForm.cs
+
+
+ Form
+
+
+ EditDiagScriptsForm.cs
+
+
Form
-
- FreeControlForm.cs
+
+ InputDialog.cs
-
+
Form
-
- ManualControlForm.cs
+
+ RTControlForm.cs
+
+ Form
+
+
+ ManualControl.cs
+
+
201904150402332_LoggingUpdgrades.cs
-
+
+ True
+ True
+ Resources.resx
+
@@ -227,35 +410,72 @@
-
+
+
Designer
+
+
+
+
+
+
+
+
+
+
+
+
+
Designer
+
+ PreserveNewest
+
-
-
-
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+
+ CustomOrientationInputDialog.cs
+
DiagnosticsForm.cs
-
- FreeControlForm.cs
+
+ EditTestForm.cs
+
+
+ EditDiagScriptsForm.cs
-
- ManualControlForm.cs
+
+ InputDialog.cs
+
+
+ RTControlForm.cs
+
+
+ ManualControl.cs
MainForm.cs
@@ -263,6 +483,30 @@
201904150402332_LoggingUpdgrades.cs
+
+ ResXFileCodeGenerator
+ Resources.Designer.cs
+
+
+
+
+ False
+ Microsoft .NET Framework 4.6.1 %28x86 and x64%29
+ true
+
+
+ False
+ .NET Framework 3.5 SP1
+ false
+
+
+
+
+
+
+
+
+
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/AASharpControllers/CoordinateCalculationController.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/AASharpControllers/CoordinateCalculationController.cs
index a1257571..e3d2d311 100644
--- a/ControlRoomApplication/ControlRoomApplication/Controllers/AASharpControllers/CoordinateCalculationController.cs
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/AASharpControllers/CoordinateCalculationController.cs
@@ -32,6 +32,7 @@ public Orientation CoordinateToOrientation(Coordinate coordinate, DateTime datet
AAS2DCoordinate Horizontal = AASCoordinateTransformation.Equatorial2Horizontal(LocalHourAngle, coordinate.Declination, Location.Latitude);
// Since AASharp considers south zero, flip the orientation 180 degrees
+ // TODO: Verify that this correctly points us north or south based on our true north offset (issue #391)
Horizontal.X += 180;
if (Horizontal.X > 360)
{
@@ -41,21 +42,24 @@ public Orientation CoordinateToOrientation(Coordinate coordinate, DateTime datet
return new Orientation(Horizontal.X, Horizontal.Y);
}
- public Coordinate OrientationToCoordinate(Orientation horizantal, DateTime datetime)
+ public Coordinate OrientationToCoordinate(Orientation currHorizontal, DateTime datetime)
{
- if (horizantal == null)
+ // We don't want to modify the current orientation, so we must create a new instance
+ Orientation horizontal = (Orientation)currHorizontal.Clone();
+
+ if (horizontal == null)
{
throw new ArgumentException("Orientation cannot be null");
}
// Since AASharp considers south zero, flip the orientation 180 degrees
- horizantal.Azimuth += 180;
- if (horizantal.Azimuth > 360)
+ horizontal.Azimuth += 180;
+ if (horizontal.Azimuth > 360)
{
- horizantal.Azimuth -= 360;
+ horizontal.Azimuth -= 360;
}
- AAS2DCoordinate equatorial = AASCoordinateTransformation.Horizontal2Equatorial(horizantal.Azimuth, horizantal.Elevation, Location.Latitude);
+ AAS2DCoordinate equatorial = AASCoordinateTransformation.Horizontal2Equatorial(horizontal.Azimuth, horizontal.Elevation, Location.Latitude);
AASDate date = new AASDate(datetime.Year, datetime.Month, datetime.Day, datetime.Hour, datetime.Minute, datetime.Second, true);
double ApparentGreenwichSiderealTime = AASSidereal.ApparentGreenwichSiderealTime(date.Julian);
@@ -70,7 +74,7 @@ public Coordinate OrientationToCoordinate(Orientation horizantal, DateTime datet
public Orientation CalculateOrientation(Appointment appt, DateTime datetime)
{
- switch (appt.Type)
+ switch (appt._Type)
{
case (AppointmentTypeEnum.POINT):
return GetPointOrientation(appt, datetime);
@@ -199,7 +203,7 @@ public Coordinate GetRasterCoordinate(Appointment appt, DateTime datetime)
// Find the width and the height of the square in points (minutes),
// rounded down to an integer
- double num_points = (appt.EndTime - appt.StartTime).TotalMinutes;
+ double num_points = (appt.end_time - appt.start_time).TotalMinutes;
double point_width = Math.Floor(Math.Sqrt(num_points));
double point_height = Math.Floor(Math.Sqrt(num_points));
if (point_width == 0 || point_height == 0)
@@ -221,7 +225,7 @@ public Coordinate GetRasterCoordinate(Appointment appt, DateTime datetime)
// finding the point_width and point_height)
// If it is, just stay at the last point of the square
double max_point = point_width * point_height;
- double point = (datetime - appt.StartTime).TotalMinutes;
+ double point = (datetime - appt.start_time).TotalMinutes;
if (point >= max_point)
{
point = max_point - 1;
@@ -256,7 +260,6 @@ public Orientation GetDriftScanOrienation(Appointment appt)
public Orientation GetFreeControlOrientation(Appointment appt, DateTime datetime)
{
- appt = DatabaseOperations.GetUpdatedAppointment(appt.Id);
Orientation free_orientation = null;
if (appt.Orientation == null)
{
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/BlkHeadUcontroler/AbstractEncoderReader.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/BlkHeadUcontroler/AbstractEncoderReader.cs
deleted file mode 100644
index 69a1a50d..00000000
--- a/ControlRoomApplication/ControlRoomApplication/Controllers/BlkHeadUcontroler/AbstractEncoderReader.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-using ControlRoomApplication.Entities;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace ControlRoomApplication.Controllers.BlkHeadUcontroler {
- public abstract class AbstractEncoderReader {
-
-
- public AbstractEncoderReader(string micro_ctrl_IP, int port) { }
- ///
- /// this should only be used for the simulator
- ///
- ///
- public AbstractEncoderReader( AbstractPLCDriver plc, string micro_ctrl_IP , int port ) { }
-
- public abstract Orientation GetCurentOrientation();
-
- }
-}
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/BlkHeadUcontroler/AbstractMicrocontroller.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/BlkHeadUcontroler/AbstractMicrocontroller.cs
deleted file mode 100644
index 94598e94..00000000
--- a/ControlRoomApplication/ControlRoomApplication/Controllers/BlkHeadUcontroler/AbstractMicrocontroller.cs
+++ /dev/null
@@ -1,68 +0,0 @@
-using ControlRoomApplication.Database;
-using ControlRoomApplication.Entities;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-
-namespace ControlRoomApplication.Controllers.BlkHeadUcontroler {
-
- ///
- /// Abstract Class for the Microcontroller
- ///
- ///
- public abstract class AbstractMicrocontroller {
-
- public AbstractMicrocontroller() { }
-
- //FourierTransform Class
- ///
- ///
- ///
- ///
-
-
-
- ///
- /// Start listetning for TCP Connection
- ///
- ///
- public abstract bool BringUp();
-
- ///
- ///
- ///
- ///
- protected void interpretData( dynamic data ) {
- double threshold = 0;
- try {
- List temps = new List();
- List accs = new List();
- foreach(dynamic element in data.data) {
- if(data.type == "temp") {
- temps.Add( Temperature.Generate( element.time , element.val , SensorLocationEnumTypeConversionHelper.FromInt( element.loc ) ) );
- threshold = 80;
-
- } else if(data.type == "acc") {
- accs.Add( Acceleration.Generate( element.time , element.val , element.x , element.y , element.z , SensorLocationEnumTypeConversionHelper.FromInt( element.loc ) ) );
- threshold = 1.65;
- } else {
- Console.WriteLine( "Datatype not found" );
- return;
- }
- if(element.val > threshold) {
- // Console.WriteLine( element.val );
- // Console.WriteLine( element.time - DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() );
- }
-
- }
- DatabaseOperations.AddSensorData( temps );
- DatabaseOperations.AddSensorData( accs );
- } catch(Exception e) {
- Console.WriteLine( e + "line 229" );
- }
- }
- }
-}
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/BlkHeadUcontroler/EncoderReader.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/BlkHeadUcontroler/EncoderReader.cs
deleted file mode 100644
index 3904f05d..00000000
--- a/ControlRoomApplication/ControlRoomApplication/Controllers/BlkHeadUcontroler/EncoderReader.cs
+++ /dev/null
@@ -1,89 +0,0 @@
-using ControlRoomApplication.Entities;
-using Newtonsoft.Json;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Net;
-using System.Net.Sockets;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace ControlRoomApplication.Controllers.BlkHeadUcontroler
-{
- ///
- ///
- ///
- public class EncoderReader : AbstractEncoderReader {
- static string message = "moshi moshi controlroom desu";
-
- TcpClient client;
- int port;
- string ip;
- IPEndPoint ipEndPoint;
- NetworkStream stream;
- ///
- /// "192.168.7.2"
- ///
- ///
- ///
- public EncoderReader( string micro_ctrl_IP , int port ) : base( micro_ctrl_IP,port ) {
- ip = micro_ctrl_IP;
- this.port = port;
- IPAddress ipAddress = IPAddress.Parse(micro_ctrl_IP);
- ipEndPoint = new IPEndPoint( ipAddress , port );
-
-
-
-
- }
- ///
- ///
- ///
- /// current orentation
- public override Orientation GetCurentOrientation() {
- try {
- client = new TcpClient();
- client.Connect( ipEndPoint );
- stream = client.GetStream();
- Byte[] data = System.Text.Encoding.ASCII.GetBytes( message );
- stream.Write( data , 0 , data.Length );
-
- data = new Byte[2048];
- String responseData = String.Empty;
-
- Int32 bytes = stream.Read( data , 0 , data.Length );
- responseData = System.Text.Encoding.ASCII.GetString( data , 0 , bytes );
- //Console.WriteLine("Received: {0}", responseData);
- dynamic respobj = null;
- try {
-
- respobj = JsonConvert.DeserializeObject( responseData );
- //Console.WriteLine(respobj.AZ+" "+ respobj.EL);
- double AZ = respobj.AZ / (2048.0) * 180;
- double EL = respobj.EL / (2048.0);
- return new Orientation( AZ , EL );
- //return new Orientation(0, (double)0);
- } catch(Exception e) {
- Console.WriteLine( "parsing exception: {0}" , e );
- return null;
- } finally {
- stream.Close();
- client.Close();
- }
- // Close everything.
- } catch(ArgumentNullException e) {
- Console.WriteLine( "ArgumentNullException: {0}" , e );
- return null;
- } catch(SocketException e) {
- //conection refused
- Console.WriteLine("SocketException: {0}", e);
- return null;
- }
-
- }
-
-
- }
-
-
-}
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/BlkHeadUcontroler/MicroControllerController.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/BlkHeadUcontroler/MicroControllerController.cs
deleted file mode 100644
index 6f6041d1..00000000
--- a/ControlRoomApplication/ControlRoomApplication/Controllers/BlkHeadUcontroler/MicroControllerController.cs
+++ /dev/null
@@ -1,205 +0,0 @@
-using Newtonsoft.Json;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Net;
-using System.Net.Sockets;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace ControlRoomApplication.Controllers.BlkHeadUcontroler
-{
- ///
- /// controler for micro prosor in the
- ///
- public class MicroControlerControler : AbstractMicrocontroller
- {
- private string local_adress;
- private int port;
- ///
- /// constructor for the micrcontroler only has bring up method which starts a server listing on ip and port
- ///
- public MicroControlerControler() : base() { }
-
- public MicroControlerControler(string IP,int port ) {
- this.port = port;
- local_adress = IP;
- }
- ///
- /// state of tcp conection
- ///
- private class StateObject
- {
- /// Client socket.
- public Socket workSocket = null;
- /// Size of receive buffer.
- public const int BufferSize = 1024;
- /// Receive buffer.
- public byte[] buffer = new byte[BufferSize];
- /// Received data string.
- public StringBuilder sb = new StringBuilder();
- }
-
- /// Thread signal.
- private static ManualResetEvent allDone = new ManualResetEvent(false);
- ///
- /// start listing for tcp conections
- ///
- public override bool BringUp()
- {
- // Establish the local endpoint for the socket.
- // The DNS name of the computer
- // running the listener is "host.contoso.com".
- IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
- IPAddress ipAddress = ipHostInfo.AddressList[ipHostInfo.AddressList.Length-1];
- ipAddress= IPAddress.Parse( local_adress );
- IPEndPoint localEndPoint = new IPEndPoint(ipAddress, port);
- Console.WriteLine("this ip "+ localEndPoint);
- // Create a TCP/IP socket.
- Socket listener = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
-
- // Bind the socket to the local endpoint and listen for incoming connections.
- try
- {
- listener.Bind(localEndPoint);
- listener.Listen(20);//takes that max number of conections to store in the backlog
- while (true)
- {
- // Set the event to nonsignaled state.
- allDone.Reset();
- // Start an asynchronous socket to listen for connections.
- //Console.WriteLine("Waiting for a connection...");
- listener.BeginAccept(new AsyncCallback(AcceptCallback),listener);
- // Wait until a connection is made before continuing.
- allDone.WaitOne();
- }
- }
- catch (Exception e)
- {
- Console.WriteLine(e.ToString());
- }
- // Console.WriteLine("\nPress ENTER to continue...");
- return true;
- }
- ///
- /// callback for accepting tcp conections
- ///
- ///
- private static void AcceptCallback(IAsyncResult ar)
- {
- // Signal the main thread to continue.
- allDone.Set();
- // Get the socket that handles the client request.
- Socket listener = (Socket)ar.AsyncState;
- Socket handler = listener.EndAccept(ar);
- // Create the state object.
- StateObject state = new StateObject();
- state.workSocket = handler;
- handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
- }
- ///
- /// callback occors when scoket has new data
- ///
- ///
- private static void ReadCallback(IAsyncResult ar)
- {
- String content = String.Empty;
- // Retrieve the state object and the handler socket
- // from the asynchronous state object.
- StateObject state = (StateObject)ar.AsyncState;
- Socket handler = state.workSocket;
- // Read data from the client socket.
- int bytesRead=0;
- try
- {
- bytesRead = handler.EndReceive(ar);
- }
- catch
- {
-
- }
-
- if (bytesRead > 0)
- {
- // There might be more data, so store the data received so far.
- state.sb.Append(Encoding.ASCII.GetString(
- state.buffer, 0, bytesRead));
-
- // Check for end-of-file tag. If it is not there, read
- // more data.
- content = state.sb.ToString();
- int eof = content.IndexOf("");
- if (eof > -1)
- {
- content = content.Substring(0, eof);
- // All the data has been read from the
- // client. Display it on the console.
- try
- {
- dynamic respobj = JsonConvert.DeserializeObject(content);
- //Console.WriteLine(respobj);
- // interpretData(respobj);
-
- Send(handler, "200-"+ respobj.uuid);
-
- }
- catch (Exception e)
- {
- if (content == "getMode")
- {
- Send(handler, "run");
- handler.Shutdown(SocketShutdown.Both);
- handler.Close();
- }
- else if (content == "alert")//TODO: if I ever decide to send alerts from the U prossor this should do something with them
- {
-
- }
- else
- {
- Send(handler, "400");//could not parse JSON
- Console.WriteLine(e+" line 165");
- }
- return;
- }
- state.sb.Clear();
- }
- //else
- //{
- // Not all data received. Get more.
- handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
- //}
- }
- }
-
- private static void Send(Socket handler, String data)
- {
- // Convert the string data to byte data using ASCII encoding.
- byte[] byteData = Encoding.ASCII.GetBytes(data);
- // Begin sending the data to the remote device.
- handler.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), handler);
- }
-
- private static void SendCallback(IAsyncResult ar)
- {
- try
- {
- // Retrieve the socket from the state object.
- Socket handler = (Socket)ar.AsyncState;
- // Complete sending the data to the remote device.
- int bytesSent = handler.EndSend(ar);
- //Console.WriteLine("Sent {0} bytes to client.", bytesSent);
- //handler.Shutdown(SocketShutdown.Both);
- //handler.Close();
- }
- catch (Exception e)
- {
- if (!(e is System.ObjectDisposedException)){
- Console.WriteLine(e.ToString()+" line 195");
- }
-
- }
- }
- }
-}
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/BlkHeadUcontroler/SimulatedEncoder.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/BlkHeadUcontroler/SimulatedEncoder.cs
deleted file mode 100644
index 8199505e..00000000
--- a/ControlRoomApplication/ControlRoomApplication/Controllers/BlkHeadUcontroler/SimulatedEncoder.cs
+++ /dev/null
@@ -1,98 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Net;
-using System.Net.Sockets;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
-using ControlRoomApplication.Entities;
-using Newtonsoft.Json;
-
-namespace ControlRoomApplication.Controllers.BlkHeadUcontroler {
- class SimulatedEncoder : AbstractEncoderReader {
-
- EncoderReader driver;
- AbstractPLCDriver plc;
- string micro_ctrl_IP;
- int port;
- bool keepalive;
- public SimulatedEncoder( string micro_ctrl_IP , int port ) : base( micro_ctrl_IP , port ) {
-
- }
- ///
- /// start a simulated encoder and driver, the simulator runs a tcp server,
- ///the simulator uses the PLC as its source of position information,
- /// and the driver is an instance of a production encoder reader to comunicate with it
- ///
- ///
- ///
- ///
- public SimulatedEncoder( AbstractPLCDriver plc , string micro_ctrl_IP , int port ) : base( plc , micro_ctrl_IP , port ) {
- keepalive = true;
- driver = new EncoderReader( micro_ctrl_IP , port );
- this.plc = plc;
- this.micro_ctrl_IP = micro_ctrl_IP;
- this.port = port;
- new Thread( new ThreadStart( run_simulation ) ).Start();
- }
-
- public override Orientation GetCurentOrientation() {
- return driver.GetCurentOrientation();
- }
-
- private void run_simulation() {
- TcpListener server = new TcpListener( IPAddress.Parse( micro_ctrl_IP ) , port );
- server.Start();
- while(keepalive) {
- Thread.Sleep( 10 );
- ClientWorking cw = new ClientWorking( server.AcceptTcpClient() , plc );
- cw.DoSomethingWithClient();
- }
- server.Stop();
- }
-
- class ClientWorking {
- private Stream ClientStream;
- private TcpClient Client;
- private AbstractPLCDriver PCL;
- public ClientWorking( TcpClient Client , AbstractPLCDriver plc ) {
- PCL = plc;
- this.Client = Client;
- ClientStream = Client.GetStream();
- }
-
- public void DoSomethingWithClient() {//once the server has a client send the position data imediatly to the driver which will then close the conection
- StreamWriter sw = new StreamWriter( ClientStream );
- StreamReader sr = new StreamReader( sw.BaseStream );
- Orientation or = PCL.read_Position();
- int az = (int)((or.Azimuth / 360.0) * 4096);
- int el = (int)((or.Elevation / 20.0) * 4096*10);
- var obj = new {
- uuid = "xxxxxxxxxxxxx" ,
- type = "position" ,
- AZ = az ,
- EL = el
- };
- //Console.WriteLine(az +" "+el);
- string json = JsonConvert.SerializeObject( obj );
- sw.WriteLine( json );
- sw.Flush();
- /*
- string data;
- try {
- while((data = sr.ReadLine()) != "exit") {
- Console.WriteLine( data );
- sw.WriteLine( data );
- sw.Flush();
- }
- } finally {
- sw.Close();
- }//*/
- }
- }
-
- }
-
-}
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/BlkHeadUcontroler/SimulatedMicrocontroller.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/BlkHeadUcontroler/SimulatedMicrocontroller.cs
deleted file mode 100644
index 8a4acfc6..00000000
--- a/ControlRoomApplication/ControlRoomApplication/Controllers/BlkHeadUcontroler/SimulatedMicrocontroller.cs
+++ /dev/null
@@ -1,80 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Threading;
-
-namespace ControlRoomApplication.Controllers.BlkHeadUcontroler {
-
- ///
- ///
- ///
- public class SimulatedMicrocontroller : AbstractMicrocontroller {
- Random rand = new Random();
- dynamic sensorData;
- private double _minMotorTemperature;
- private double _maxMotorTemperature;
- private List Templocations = new List { 0 , 1 , 3 };
- private List ACClocations = new List { 0 , 1 , 2 };
- private Thread simthread;
- ///
- ///Set the minimum and maximum temperature for the motors
- ///
- public SimulatedMicrocontroller( double minMotorTemperature , double maxMotorTemperature ) {
- _minMotorTemperature = minMotorTemperature;
- _maxMotorTemperature = maxMotorTemperature;
-
- }
-
- ///
- /// start the simulation thread
- ///
- public override bool BringUp() {
- simthread = new Thread( new ThreadStart( Run_sim ) );
- simthread.Start();
- return true;
- }
-
- private void Run_sim() {
- while(true) {
- interpretData( generateTemperatureData() );
- interpretData( generateAccelerometerData() );
- Thread.Sleep( 1000 );
- }
- }
-
-
- ///
- /// Creates a data point with a random value, the time it was created (now), and type: temp
- ///
- /// Returns SensorData containing the value, time, and type, and an int representing location
- public dynamic generateTemperatureData() {
- var temperatureList = new dynamic[1];
-
- for(int i = 0; i < temperatureList.Length; i++) {
- int index = rand.Next( Templocations.Count );
- temperatureList[i] = new { val = rand.Next( (int)_minMotorTemperature , (int)_maxMotorTemperature ) , time = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() + i , loc = Templocations[index] };
-
- }
- var temperatureData = new { type = "temp" , data = temperatureList };
- return temperatureData;
- }
-
-
- public dynamic generateAccelerometerData() {
- var list = new dynamic[100];
- double x, y, z;
- for(int i = 0; i < list.Length; i++) {
- x = rand.Next();
- y = rand.Next();
- z = rand.Next();
- int index = rand.Next( ACClocations.Count );
- list[i] = new { x = x , y = y , z = z , val = Math.Sqrt( x * x + y * y + z * z ) , time = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() + (i * 10) , loc = ACClocations[index] };
-
- }
- var accelData = new { type = "acc" , data = list };
- return accelData;
- }
- }
-}
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/Communications/AES.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/Communications/AES.cs
new file mode 100644
index 00000000..78b22ac5
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/Communications/AES.cs
@@ -0,0 +1,93 @@
+using ControlRoomApplication.Util;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Security.Cryptography;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ControlRoomApplication.Controllers.Communications
+{
+ ///
+ /// AES class that handles both the decryption and encryption of text using AES-256
+ ///
+ public static class AES
+ {
+ ///
+ /// Encrypts the given string using the given key and iv, and returns the encrypted string
+ ///
+ ///
+ ///
+ ///
+ /// Encrypted input string
+ public static string Encrypt(string input, string key, string iv)
+ {
+ if (string.IsNullOrWhiteSpace(input))
+ {
+ return input;
+ }
+ using (RijndaelManaged rijndaelManaged = new RijndaelManaged())
+ {
+ rijndaelManaged.Mode = CipherMode.CBC;
+ rijndaelManaged.Padding = PaddingMode.PKCS7;
+ rijndaelManaged.FeedbackSize = 128;
+
+ rijndaelManaged.Key = Encoding.UTF8.GetBytes(key);
+ rijndaelManaged.IV = Encoding.UTF8.GetBytes(iv);
+
+ ICryptoTransform encryptor = rijndaelManaged.CreateEncryptor(rijndaelManaged.Key, rijndaelManaged.IV);
+ using (MemoryStream msEncrypt = new MemoryStream())
+ {
+ using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
+ {
+ using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
+ {
+ swEncrypt.Write(input);
+ }
+ byte[] bytes = msEncrypt.ToArray();
+ return Convert.ToBase64String(bytes);
+ }
+ }
+ }
+ }
+
+ ///
+ /// Decrypts the provided string using the provided key and iv, then returns the decrypted string
+ ///
+ ///
+ ///
+ ///
+ /// Decrypted input string
+ public static string Decrypt(string input, string key, string iv)
+ {
+ if (string.IsNullOrWhiteSpace(input))
+ {
+ return input;
+ }
+ byte[] buffer = Convert.FromBase64String(input);
+ using (RijndaelManaged rijndaelManaged = new RijndaelManaged())
+ {
+ rijndaelManaged.Mode = CipherMode.CBC;
+ rijndaelManaged.Padding = PaddingMode.PKCS7;
+ rijndaelManaged.FeedbackSize = 128;
+
+ rijndaelManaged.Key = Encoding.UTF8.GetBytes(key);
+ rijndaelManaged.IV = Encoding.UTF8.GetBytes(iv);
+
+ ICryptoTransform decryptor = rijndaelManaged.CreateDecryptor(rijndaelManaged.Key, rijndaelManaged.IV);
+ using (MemoryStream msEncrypt = new MemoryStream(buffer))
+ {
+ using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, decryptor, CryptoStreamMode.Read))
+ {
+ using (StreamReader srEncrypt = new StreamReader(csEncrypt))
+ {
+ return srEncrypt.ReadToEnd();
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/Communications/DataToCSV.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/Communications/DataToCSV.cs
new file mode 100644
index 00000000..eb371d6b
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/Communications/DataToCSV.cs
@@ -0,0 +1,107 @@
+using ControlRoomApplication.Constants;
+using ControlRoomApplication.Entities;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Reflection;
+using System.Text;
+using System.Threading;
+
+namespace ControlRoomApplication.Controllers.Communications
+{
+ public class DataToCSV
+ {
+ private static readonly log4net.ILog logger =
+ log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
+
+ public static bool ExportToCSV(List Data, string fname)
+ {
+ StringBuilder sb = new StringBuilder();
+ string path = AppDomain.CurrentDomain.BaseDirectory;
+
+ string final_loc = Path.Combine(path, $"{fname}.csv");
+
+ PropertyInfo[] info = typeof(RFData).GetProperties();
+
+ string header = "";
+ bool success = false;
+
+ try
+ {
+ if (!File.Exists(final_loc))
+ {
+ FileStream file = File.Create(final_loc);
+ file.Close();
+
+ foreach (PropertyInfo property in info)
+ {
+ // We only want the TimeCaptured and Intensity fields to be listed in the CSV
+ if (property.Name != "Appointment" && property.Name != "Id" && property.Name != "appointment_id")
+ {
+ header += property.Name + ", ";
+ }
+ }
+ header = header.Substring(0, header.Length - 2);
+ sb.AppendLine(header);
+ TextWriter sw = new StreamWriter(final_loc, true);
+ sw.Write(sb.ToString());
+ sw.Close();
+ }
+
+ foreach (RFData rf in Data)
+ {
+ sb = new StringBuilder();
+ var line = "";
+ foreach (PropertyInfo property in info)
+ {
+ if (property.Name != "Appointment" && property.Name != "Id" && property.Name != "appointment_id")
+ {
+ line += property.GetValue(rf, null) + ", ";
+ }
+ }
+ line = line.Substring(0, line.Length - 2);
+ sb.AppendLine(line);
+ using (TextWriter sw = new StreamWriter(final_loc, true))
+ {
+ sw.Write(sb);
+ }
+ }
+ success = true;
+ }
+ catch (Exception e)
+ {
+ Console.Out.WriteLine($"Could not write data to CSV! Error: {e}");
+ success = false;
+ }
+ return success;
+ }
+
+ public static bool DeleteCSVFileWhenDone(string filepath)
+ {
+ bool success = false;
+ int numAttempts = 0;
+
+ while (numAttempts < MiscellaneousConstants.MAX_ATTEMPTS)
+ {
+ try
+ {
+ File.Delete(filepath);
+ success = true;
+ break;
+ }
+ catch (IOException)
+ {
+ numAttempts++;
+ Thread.Sleep(100);
+ }
+ }
+
+ if (numAttempts == MiscellaneousConstants.MAX_ATTEMPTS)
+ {
+ logger.Debug($"Could not delete file at '{filepath}'! File may be stuck in a locked state.");
+ }
+
+ return success;
+ }
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/Communications/EmailNotifications.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/Communications/EmailNotifications.cs
new file mode 100644
index 00000000..1d4a82ae
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/Communications/EmailNotifications.cs
@@ -0,0 +1,185 @@
+using ControlRoomApplication.Entities;
+using System;
+using System.Collections.Generic;
+using System.Net.Mail;
+using System.Net.Mime;
+using System.Threading;
+using Amazon.SimpleEmail;
+using Amazon.SimpleEmail.Model;
+using Amazon;
+using ControlRoomApplication.Database;
+using System.Threading.Tasks;
+
+namespace ControlRoomApplication.Controllers.Communications
+{
+ public class EmailNotifications
+ {
+ public static Task sendToAllAdmins(string subject, string body, string sender = "system@ycpradiotelescope.com", bool testflag = false)
+ {
+ bool success = false;
+
+ Thread t = new Thread(() =>
+ {
+
+ List admins = new List();
+ if (testflag)
+ {
+ // If you want physical proof that this tests, change the below fields to your own credentials
+ // I've already proven it works, so I took mine out. I don't like getting constant test emails.
+ // Or I guess you could create an account for good ol' Test User, but that's unnecessary in my opinion.
+ admins.Add(new User("Test", "User", "testradiotelescopeuser@ycp.edu", NotificationTypeEnum.ALL));
+ }
+ else
+ {
+ admins = DatabaseOperations.GetAllAdminUsers();
+ }
+
+ foreach (User u in admins)
+ {
+ if (u._Notification_Type == NotificationTypeEnum.ALL || u._Notification_Type == NotificationTypeEnum.EMAIL)
+ {
+ try
+ {
+ // All-admin notifications will always be sent from SYSTEM by default.
+ EmailNotifications.sendEmail(u, subject, body, sender);
+ success = true;
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine($"ERROR: Email could not send: {e}");
+ success = false;
+ }
+ }
+ }
+ });
+
+ t.Priority = ThreadPriority.Lowest;
+ t.Start();
+
+ // If it is a unit test, we want to wait for the thread to finish running before returning a value
+ if (testflag) t.Join();
+
+ return Task.FromResult(success);
+ }
+
+ public static Task sendToUser(User u, string subject, string body, string sender, string AttachmentPath = null, bool testflag = false)
+ {
+ bool success = false;
+
+ Thread t = new Thread(() =>
+ {
+ try
+ {
+ EmailNotifications.sendEmail(u, subject, body, sender, AttachmentPath);
+ success = true;
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine($"ERROR: Email could not send: {e}");
+ success = false;
+ }
+ });
+
+ t.Priority = ThreadPriority.Lowest;
+ t.Start();
+
+ // If it is a unit test, we want to wait for the thread to finish running before returning a value
+ if (testflag) t.Join();
+
+ return Task.FromResult(success);
+ }
+
+ private static void sendEmail(User user, string subject, string body, string sender, string AttachPath = null)
+ {
+ using (var client = new AmazonSimpleEmailServiceClient(RegionEndpoint.USEast2))
+ {
+ if (AttachPath == null)
+ {
+ var sendRequest = new SendEmailRequest
+ {
+ Source = sender,
+ Destination = new Destination
+ {
+ ToAddresses = new List { user.email_address }
+ },
+ Message = new Message
+ {
+ Subject = new Content(subject),
+ Body = new Body
+ {
+ Html = new Content
+ {
+ Charset = "UTF-8",
+ Data = generateHtml(subject, body)
+ },
+ Text = new Content
+ {
+ Charset = "UTF-8",
+ Data = body
+ }
+ }
+ }
+ };
+
+ try
+ {
+ Console.WriteLine("Sending email using Amazon SES...");
+ var response = client.SendEmail(sendRequest);
+ Console.WriteLine("The email was sent successfully.");
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("The email was not sent.");
+ Console.WriteLine($"Error: {e}");
+ }
+ }
+ else
+ {
+ SendRawEmailRequest request = new SendRawEmailRequest();
+ request.RawMessage = new RawMessage();
+
+ // message is an instance of a System.Net.Mail.MailMessage
+ MailMessage message = new MailMessage(
+ sender,
+ user.email_address,
+ subject,
+ body);
+
+ using (Attachment data = new Attachment(AttachPath, MediaTypeNames.Application.Octet))
+ {
+ ContentDisposition disposition = data.ContentDisposition;
+ disposition.CreationDate = System.IO.File.GetCreationTime(AttachPath);
+ disposition.ModificationDate = System.IO.File.GetLastWriteTime(AttachPath);
+ disposition.ReadDate = System.IO.File.GetLastAccessTime(AttachPath);
+
+ message.Attachments.Add(data);
+
+ request.RawMessage.Data = SendAttachmentHelper.ConvertMailMessageToMemoryStream(message);
+ }
+ try
+ {
+ Console.WriteLine("Sending email using Amazon SES...");
+ var response = client.SendRawEmail(request);
+ Console.WriteLine("The email was sent successfully.");
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("The email was not sent.");
+ Console.WriteLine($"Error: {e}");
+ }
+ }
+ }
+ }
+
+ private static string generateHtml(string subject, string body)
+ {
+ return $@"
+
+
+ {subject}
+ {body}
+
+";
+ }
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/Communications/Enumerations/ParseTCPCommandResultEnum.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/Communications/Enumerations/ParseTCPCommandResultEnum.cs
new file mode 100644
index 00000000..8a64e2a7
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/Communications/Enumerations/ParseTCPCommandResultEnum.cs
@@ -0,0 +1,55 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ControlRoomApplication.Controllers.Communications.Enumerations
+{
+ ///
+ /// This enumeration is used to descriptively describe any and all errors the control room
+ /// might encounter when parsing remote listener strings. To be used ONLY IN REMOTELISTENER for now.
+ ///
+ public enum ParseTCPCommandResultEnum
+ {
+ ///
+ /// The command was parsed correctly
+ ///
+ Success,
+
+ ///
+ /// The version number was not found or is invalid
+ ///
+ InvalidVersion,
+
+ ///
+ /// The command type (Coordinate move, script, relative move, all stop, etc.) was not found or invalid
+ ///
+ InvalidCommandType,
+
+ ///
+ /// The command type was valid, but the arguments passed were not.
+ /// E.g. AZ: 30 EL: 120 --> EL is out of range
+ /// E.g. SENSOR_OVERRIDE: GATE_THAT_DOESNT_EXIST
+ ///
+ InvalidCommandArgs,
+
+ ///
+ /// The command type was valid, but did not receive required arguments
+ /// E.g. AZ: 30 (no EL) --> EL is not given
+ /// E.g. SENSOR_OVERRIDE: (nothing)
+ ///
+ MissingCommandArgs,
+
+ ///
+ /// The script name requested was not found or is invalid
+ ///
+ InvalidScript,
+
+ ///
+ /// The request type was not found
+ ///
+ InvalidRequestType
+
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/Communications/ExecuteTCPCommandResult.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/Communications/ExecuteTCPCommandResult.cs
new file mode 100644
index 00000000..a2578783
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/Communications/ExecuteTCPCommandResult.cs
@@ -0,0 +1,37 @@
+using ControlRoomApplication.Controllers.PLCCommunication.PLCDrivers.MCUManager.Enumerations;
+using ControlRoomApplication.Controllers.Communications.Enumerations;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ControlRoomApplication.Controllers.Communications
+{
+ ///
+ /// The object returned as the result of executing a command received inside of RemoteListener.
+ /// The command will first be parsed (via ParseRLString() ), and then, if safe to do so, will execute.
+ /// The object contains a MovementResult which specifies the resulting action of any given movement sent to the PLC.
+ /// The error message string is set on error (e.g., MvmtResult!=success) and will contain a string from TCPCommunicationConstants
+ /// indicating what went wrong and where.
+ ///
+ public class ExecuteTCPCommandResult
+ {
+ public MovementResult movementResult { get; set; }
+ public MCUResetResult resetResult { get; set; }
+ public String errorMessage { get; set; }
+
+ // Optional ErrMessage param that can be set if an error occurred, This will allow descriptive communication between CR and Mobile
+ public ExecuteTCPCommandResult(MovementResult mvmtResult, String errMessage = null)
+ {
+ movementResult = mvmtResult;
+ errorMessage = errMessage;
+ }
+
+ public ExecuteTCPCommandResult(MCUResetResult resetResult, String errMessage = null)
+ {
+ resetResult = resetResult;
+ errorMessage = errMessage;
+ }
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/Communications/MessageType.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/Communications/MessageType.cs
new file mode 100644
index 00000000..e702cde1
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/Communications/MessageType.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.ComponentModel;
+using System.Reflection;
+
+namespace ControlRoomApplication.Controllers
+{
+ public enum MessageTypeEnum
+ {
+ [Description("Your YCAS Radio Telescope appointment has completed.")]
+ APPOINTMENT_COMPLETION,
+ [Description("Your YCAS Radio Telescope appointment has been cancelled.")]
+ APPOINTMENT_CANCELLED,
+ [Description("Your YCAS Radio Telescope appointment has started.")]
+ APPOINTMENT_STARTED
+ }
+
+ public static class MessageTypeExtension
+ {
+ public static string GetDescription(MessageTypeEnum e)
+ {
+ FieldInfo type = e.GetType().GetField(e.ToString());
+ var attrs = type.GetCustomAttributes(typeof(DescriptionAttribute), true);
+
+ string message = ((DescriptionAttribute)attrs[0]).Description;
+
+ return message;
+ }
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/Communications/ParseTCPCommandResult.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/Communications/ParseTCPCommandResult.cs
new file mode 100644
index 00000000..daaf3e6f
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/Communications/ParseTCPCommandResult.cs
@@ -0,0 +1,34 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using ControlRoomApplication.Controllers.Communications.Enumerations;
+using ControlRoomApplication.Constants;
+
+namespace ControlRoomApplication.Controllers.Communications
+{
+ ///
+ /// This is the object returned as a result of the ParseRLString() function inside of RemoteListener.
+ /// A command comes in as a string inside of RemoteListener and gets passed into the ParseRLString.
+ /// This object is the result of attempting to parse said command; a ParseTCPCommunicationResult enum is set indicating if the parse
+ /// was successful, or what error occured. On error, the errMessage string is set to provide a descriptive error back to the mobile app or control room.
+ ///
+ ///
+ ///
+ public class ParseTCPCommandResult
+ {
+ public ParseTCPCommandResultEnum parseTCPCommandResultEnum { get; set; }
+ public String errorMessage { get; set; }
+ public String[] parsedString { get; set; }
+
+ // Optional ErrMessage param that can be set if an error occurred, This will allow descriptive communication between CR and Mobile
+ public ParseTCPCommandResult(ParseTCPCommandResultEnum parseResultEnum, String[] parsedStringArr, String errMessage = null)
+ {
+ parseTCPCommandResultEnum = parseResultEnum;
+ parsedString = parsedStringArr;
+ errorMessage = errMessage;
+
+ }
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/Communications/RemoteListener.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/Communications/RemoteListener.cs
new file mode 100644
index 00000000..8b07de4f
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/Communications/RemoteListener.cs
@@ -0,0 +1,931 @@
+using System;
+using System.IO;
+using System.Net;
+using System.Net.Sockets;
+using System.Text;
+using System.Threading;
+using ControlRoomApplication.Entities;
+using ControlRoomApplication.Main;
+using ControlRoomApplication.Database;
+using ControlRoomApplication.Util;
+using ControlRoomApplication.Constants;
+using ControlRoomApplication.Controllers.PLCCommunication.PLCDrivers.MCUManager;
+using ControlRoomApplication.Controllers.SensorNetwork;
+using ControlRoomApplication.Controllers.PLCCommunication.PLCDrivers.MCUManager.Enumerations;
+using ControlRoomApplication.Controllers.Communications;
+using ControlRoomApplication.Controllers.Communications.Enumerations;
+
+
+namespace ControlRoomApplication.Controllers
+{
+ public class RemoteListener
+ {
+
+ private static readonly log4net.ILog logger =
+ log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
+
+ public TcpListener server = null;
+ private Thread TCPMonitoringThread;
+ private bool KeepTCPMonitoringThreadAlive;
+ public RadioTelescopeController rtController;
+ private ControlRoom controlRoom;
+
+ private bool waitingForConn = true;
+
+ public RemoteListener(int port, ControlRoom control)
+ {
+ logger.Debug(Utilities.GetTimeStamp() + ": Setting up remote listener");
+ server = new TcpListener(port);
+
+ controlRoom = control;
+
+ // Start listening for client requests.
+ server.Start();
+
+ KeepTCPMonitoringThreadAlive = true;
+ // start the listening thread
+ TCPMonitoringThread = new Thread(new ThreadStart(TCPMonitoringRoutine));
+
+ TCPMonitoringThread.Start();
+ }
+
+ public void TCPMonitoringRoutine()
+ {
+ // Buffer for reading data
+ Byte[] bytes = new Byte[512];
+ String data = null;
+
+ // Enter the listening loop.
+ while (KeepTCPMonitoringThreadAlive)
+ {
+ if (waitingForConn)
+ {
+ logger.Debug(Utilities.GetTimeStamp() + ": Waiting for a connection... ");
+ waitingForConn = false;
+ }
+
+ // Place each command in its own asynchronous thread so that we can run commands in parallel
+ if (server.Pending())
+ {
+ waitingForConn = true;
+ new Thread(() =>
+ {
+ using (TcpClient client = server.AcceptTcpClient())
+ {
+ logger.Debug(Utilities.GetTimeStamp() + ": TCP Client connected!");
+
+ data = null;
+ // Get a stream object for reading and writing
+ using (NetworkStream stream = client.GetStream())
+ {
+ int i;
+
+ // Loop to receive all the data sent by the client.
+ if ((i = readFromStream(stream, bytes)) != 0)
+ {
+ // Reset the encrypted bool because we don't know if every command sent will be encrypted (we will have to check each time)
+ bool encrypted = false;
+
+ // Translate data bytes to ASCII string.
+ data = Encoding.ASCII.GetString(bytes, 0, i);
+
+ logger.Debug(Utilities.GetTimeStamp() + ": Received: " + data);
+
+ // If the command is encrypted, decrypt the command and proceed as normal
+ Tuple dataPair = Utilities.CheckEncrypted(data);
+ data = dataPair.Item1;
+ encrypted = dataPair.Item2;
+
+ string myWriteBuffer = null;
+
+ // Inform mobile command received
+ writeBackToClient(data, stream, encrypted);
+
+ // Process the data sent by the client.
+ data = data.ToUpper();
+
+ // if processing the data fails, report an error message
+ ParseTCPCommandResult parsedTCPCommandResult = ParseRLString(data);
+ if (parsedTCPCommandResult.parseTCPCommandResultEnum != ParseTCPCommandResultEnum.Success)
+ {
+ // send back a failure response
+ logger.Info("Parsing command failed with ERROR: " + parsedTCPCommandResult.errorMessage);
+ myWriteBuffer = "Parsing command failed with error: " + parsedTCPCommandResult.errorMessage;
+ writeBackToClient(myWriteBuffer, stream, encrypted);
+ }
+ // else the parsing was successful, attempt to run the command
+ else
+ {
+ // if script inform which script is running, else just command type
+ if (parsedTCPCommandResult.parsedString[TCPCommunicationConstants.COMMAND_TYPE] == "SCRIPT")
+ {
+ logger.Debug(Utilities.GetTimeStamp() + ": Successfully parsed command " + data + ". Beginning requested movement " +
+ parsedTCPCommandResult.parsedString[TCPCommunicationConstants.COMMAND_TYPE] + " " +
+ parsedTCPCommandResult.parsedString[TCPCommunicationConstants.SCRIPT_NAME] + "...");
+ string startedCommandMsg = "Successfully parsed command " + data + ". Beginning requested movement " +
+ parsedTCPCommandResult.parsedString[TCPCommunicationConstants.COMMAND_TYPE] + " " +
+ parsedTCPCommandResult.parsedString[TCPCommunicationConstants.SCRIPT_NAME] + "...";
+ writeBackToClient(startedCommandMsg, stream, encrypted);
+ // writeback eta to client
+ int estMoveTime = ScriptETA(parsedTCPCommandResult.parsedString[TCPCommunicationConstants.SCRIPT_NAME]);
+ logger.Info("Script " + parsedTCPCommandResult.parsedString[TCPCommunicationConstants.SCRIPT_NAME] +
+ " has an estimated time of " + estMoveTime + " ms");
+ writeBackToClient(("Script " + parsedTCPCommandResult.parsedString[TCPCommunicationConstants.SCRIPT_NAME] +
+ " has an estimated time of " + estMoveTime + " ms"), stream, encrypted);
+
+ }
+ else
+ {
+ logger.Debug(Utilities.GetTimeStamp() + ": Successfully parsed command " + data + ". Beginning requested movement " +
+ parsedTCPCommandResult.parsedString[TCPCommunicationConstants.COMMAND_TYPE] + "...");
+ string startedCommandMsg = "Successfully parsed command " + data + ". Beginning requested movement " +
+ parsedTCPCommandResult.parsedString[TCPCommunicationConstants.COMMAND_TYPE] + "...";
+ writeBackToClient(startedCommandMsg, stream, encrypted);
+
+ switch (parsedTCPCommandResult.parsedString[TCPCommunicationConstants.COMMAND_TYPE])
+ {
+ case "ORIENTATION_MOVE":
+ try
+ {
+ // Attempt to parse double values
+ double azAbs = Double.Parse(parsedTCPCommandResult.parsedString[TCPCommunicationConstants.ORIENTATION_MOVE_AZ]);
+ double elAbs = Double.Parse(parsedTCPCommandResult.parsedString[TCPCommunicationConstants.ORIENTATION_MOVE_EL]);
+
+ int mvmtTimeAbs = AbsoluteMovementETA(new Orientation(azAbs, elAbs));
+ writeBackToClient("ORIENTATION_MOVE TO AZ " + azAbs + " and EL " + elAbs + " has an estimated time of " + mvmtTimeAbs + " ms", stream, encrypted);
+ }
+ catch (Exception e)
+ {
+ writeBackToClient("An exception occurred attempting to parse AZ and/or EL values: " + e.Message, stream, encrypted);
+ }
+ break;
+
+ case "RELATIVE_MOVE":
+ try
+ {
+ // Attempt to parse double values
+ double azRelative = Double.Parse(parsedTCPCommandResult.parsedString[TCPCommunicationConstants.RELATIVE_MOVE_AZ]);
+ double elRelative = Double.Parse(parsedTCPCommandResult.parsedString[TCPCommunicationConstants.RELATIVE_MOVE_EL]);
+ int mvmtTimeRelative = RelativeMovementETA(new Orientation(azRelative, elRelative));
+
+ writeBackToClient("RELATIVE_MOVE BY AZ " + azRelative + " and EL " + elRelative + " has an estimated time of " +
+ mvmtTimeRelative + " ms", stream, encrypted);
+ }
+ catch (Exception e)
+ {
+ writeBackToClient("An exception occurred attempting to parse AZ and/or EL values: " + e.Message, stream, encrypted);
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ // Now that we have finished parsing our command, execute it since it has been determined to be valid
+ ExecuteTCPCommandResult executeTCPCommandResult = ExecuteRLCommand(parsedTCPCommandResult.parsedString);
+
+ // inform user of the result of command
+ if (executeTCPCommandResult.movementResult != MovementResult.Success)
+ {
+ logger.Debug(Utilities.GetTimeStamp() + ": Command " + data + " failed with error: " + executeTCPCommandResult.errorMessage);
+ myWriteBuffer = "Command " + data + " failed with error: " + executeTCPCommandResult.errorMessage;
+ writeBackToClient(myWriteBuffer, stream, encrypted);
+ }
+ else
+ {
+ switch (parsedTCPCommandResult.parsedString[TCPCommunicationConstants.COMMAND_TYPE])
+ {
+ // we write back different in the case of a request command. Otherwise, the default is just successfully completing a command
+ case "REQUEST":
+ switch (parsedTCPCommandResult.parsedString[TCPCommunicationConstants.REQUEST_TYPE])
+ {
+ case "MVMT_DATA":
+ writeBackToClient(executeTCPCommandResult.errorMessage, stream, encrypted);
+ logger.Debug(Utilities.GetTimeStamp() + ": " + executeTCPCommandResult.errorMessage);
+ break;
+ }
+ break;
+
+ default:
+ logger.Debug(Utilities.GetTimeStamp() + ": SUCCESSFULLY COMPLETED COMMAND: " + data);
+ // send back a success response -- finished command
+ myWriteBuffer = "SUCCESSFULLY COMPLETED COMMAND: " + data;
+ writeBackToClient(myWriteBuffer, stream, encrypted);
+ break;
+ }
+ }
+ }
+
+ // Shutdown and end connection
+ client.Close();
+ client.Dispose();
+ stream.Close();
+ stream.Dispose();
+ }
+ }
+ }
+ }).Start(); // begin our worker thread to execute our TCP command
+ }
+ }
+ }
+
+ public bool RequestToKillTCPMonitoringRoutine()
+ {
+ logger.Info(Utilities.GetTimeStamp() + ": Killing TCP Monitoring Routine");
+
+ KeepTCPMonitoringThreadAlive = false;
+
+ try
+ {
+ server.Stop();
+ TCPMonitoringThread.Join();
+
+ }
+ catch (Exception e)
+ {
+ if ((e is ThreadStateException) || (e is ThreadInterruptedException))
+ {
+ return false;
+ }
+ else
+ {
+ // Unexpected exception
+ throw e;
+ }
+ }
+
+ return true;
+ }
+
+ public ExecuteTCPCommandResult ExecuteRLCommand(String[] splitCommandString)
+ {
+ // Convert version from string to double. This is the first value in our string before the "|" character.
+ // From here we will direct to the appropriate parsing for said version
+ double version = 0.0;
+ try
+ {
+ version = Double.Parse(splitCommandString[TCPCommunicationConstants.VERSION_NUM]);
+ }
+ catch (Exception e)
+ {
+ String errMessage = TCPCommunicationConstants.VERSION_CONVERSION_ERR + e.Message;
+ return new ExecuteTCPCommandResult(MovementResult.InvalidCommand, errMessage);
+
+ }
+
+ // Use appropriate parsing for given version
+ if (version >= 1.1)
+ {
+ string command = splitCommandString[TCPCommunicationConstants.COMMAND_TYPE];
+
+ if (command == "RESET_MCU_BIT")
+ {
+ if (rtController.ResetMCUErrors())
+ {
+ return new ExecuteTCPCommandResult(MCUResetResult.Success, null);
+ }
+ else
+ {
+ return new ExecuteTCPCommandResult(MCUResetResult.Failed, "Failed to reset MCU error bit.");
+ }
+ }
+ else if (command == "REQUEST")
+ {
+ switch (splitCommandString[TCPCommunicationConstants.REQUEST_TYPE])
+ {
+ case "MVMT_DATA":
+ return new ExecuteTCPCommandResult(MovementResult.Success, GetMovementData(version));
+
+ default:
+ return new ExecuteTCPCommandResult(MovementResult.InvalidCommand, TCPCommunicationConstants.INVALID_REQUEST_TYPE + splitCommandString[TCPCommunicationConstants.REQUEST_TYPE]);
+ }
+ }
+ }
+ if (version >= 1.0)
+ {
+ // command is placed after pike and before colon; get it here
+ // | | > | TIME
+ string command = splitCommandString[TCPCommunicationConstants.COMMAND_TYPE];
+
+ if (command=="ORIENTATION_MOVE")
+ {
+ // we have a move command coming in
+ rtController.ExecuteRadioTelescopeControlledStop(MovementPriority.GeneralStop);
+
+ // get azimuth and orientation
+ double azimuth = 0.0;
+ double elevation = 0.0;
+ try
+ {
+ azimuth = Convert.ToDouble(splitCommandString[TCPCommunicationConstants.ORIENTATION_MOVE_AZ]);
+ elevation = Convert.ToDouble(splitCommandString[TCPCommunicationConstants.ORIENTATION_MOVE_EL]);
+ }
+ catch (Exception e)
+ {
+ String errMessage = TCPCommunicationConstants.AZ_EL_CONVERSION_ERR + e.Message;
+ return new ExecuteTCPCommandResult(MovementResult.InvalidCommand, errMessage);
+ }
+
+ logger.Debug(Utilities.GetTimeStamp() + ": Azimuth " + azimuth);
+ logger.Debug(Utilities.GetTimeStamp() + ": Elevation " + elevation);
+
+ Orientation movingTo = new Orientation(azimuth, elevation);
+
+ // check result of movement, if it fails we return the result type along with an error message.
+ // The command parse was successful however, so we indicate that
+ MovementResult result = rtController.MoveRadioTelescopeToOrientation(movingTo, MovementPriority.Manual);
+ if (result != MovementResult.Success)
+ {
+ return new ExecuteTCPCommandResult(result, TCPCommunicationConstants.ORIENTATION_MOVE_ERR + result.ToString());
+ }
+ else
+ // everything was successful
+ {
+ return new ExecuteTCPCommandResult(result);
+ }
+
+ }
+ else if (command=="RELATIVE_MOVE")
+ {
+
+ // we have a relative movement command
+ rtController.ExecuteRadioTelescopeControlledStop(MovementPriority.GeneralStop);
+
+ // get azimuth and orientation
+ double azimuth = 0.0;
+ double elevation = 0.0;
+
+ try
+ {
+ azimuth = Convert.ToDouble(splitCommandString[TCPCommunicationConstants.RELATIVE_MOVE_AZ]);
+ elevation = Convert.ToDouble(splitCommandString[TCPCommunicationConstants.RELATIVE_MOVE_EL]);
+ }
+ catch (Exception e)
+ {
+ String errMessage = TCPCommunicationConstants.AZ_EL_CONVERSION_ERR + e.Message;
+ return new ExecuteTCPCommandResult(MovementResult.InvalidCommand, errMessage);
+ }
+
+ logger.Debug(Utilities.GetTimeStamp() + ": Azimuth " + azimuth);
+ logger.Debug(Utilities.GetTimeStamp() + ": Elevation " + elevation);
+
+ Orientation movingBy = new Orientation(azimuth, elevation);
+
+ MovementResult result = rtController.MoveRadioTelescopeByXDegrees(movingBy, MovementPriority.Manual);
+ if (result != MovementResult.Success)
+ {
+ // the actual movement failed
+ return new ExecuteTCPCommandResult(result, TCPCommunicationConstants.RELATIVE_MOVE_ERR + result.ToString());
+ }
+ else
+ {
+ // everything was successful
+ return new ExecuteTCPCommandResult(result);
+ }
+ }
+ else if (command=="SET_OVERRIDE")
+ {
+ string sensorToOverride = splitCommandString[TCPCommunicationConstants.SENSOR_TO_OVERRIDE];
+ bool doOverride = splitCommandString[TCPCommunicationConstants.DO_OVERRIDE] == "TRUE" ? true : false;
+ switch (sensorToOverride)
+ {
+ // Non-PLC Overrides
+ case "WEATHER_STATION":
+ controlRoom.weatherStationOverride = doOverride;
+ rtController.setOverride("weather station", doOverride);
+ DatabaseOperations.SetOverrideForSensor(SensorItemEnum.WEATHER_STATION, doOverride);
+ break;
+
+ // PLC Overrides
+ case "MAIN_GATE":
+ rtController.setOverride("main gate", doOverride);
+ break;
+
+ // Proximity overrides
+ case "ELEVATION_LIMIT_0":
+ rtController.setOverride("elevation proximity (1)", doOverride);
+ break;
+
+ case "ELEVATION_LIMIT_90":
+ rtController.setOverride("elevation proximity (2)", doOverride);
+ break;
+
+ // Sensor network overrides
+ case "AZ_ABS_ENC":
+ rtController.setOverride("azimuth absolute encoder", doOverride);
+ break;
+
+ case "EL_ABS_ENC":
+ rtController.setOverride("elevation absolute encoder", doOverride);
+ break;
+
+ case "AZ_ACC":
+ rtController.setOverride("azimuth motor accelerometer", doOverride);
+ break;
+
+ case "EL_ACC":
+ rtController.setOverride("elevation motor accelerometer", doOverride);
+ break;
+
+ case "CB_ACC":
+ rtController.setOverride("counterbalance accelerometer", doOverride);
+ break;
+
+ case "AZIMUTH_MOT_TEMP":
+ rtController.setOverride("azimuth motor temperature", doOverride);
+ break;
+
+ case "ELEVATION_MOT_TEMP":
+ rtController.setOverride("elevation motor temperature", doOverride);
+ break;
+
+ // If no case is reached, the sensor is not valid. Return appropriately
+ default:
+ return new ExecuteTCPCommandResult(MovementResult.InvalidCommand, TCPCommunicationConstants.INVALID_SENSOR_OVERRIDE + sensorToOverride);
+ }
+
+ return new ExecuteTCPCommandResult(MovementResult.Success);
+
+ }
+ else if (command=="SCRIPT")
+ {
+ // we have a move command coming in
+ rtController.ExecuteRadioTelescopeControlledStop(MovementPriority.GeneralStop);
+
+ // Retrieve script name used for switch case
+ string script = splitCommandString[TCPCommunicationConstants.SCRIPT_NAME];
+ MovementResult result = MovementResult.None;
+
+ logger.Debug(Utilities.GetTimeStamp() + ": Script " + script);
+
+ switch (script) {
+
+ case "DUMP":
+ result = rtController.SnowDump(MovementPriority.Manual);
+ break;
+
+ case "FULL_EV":
+ result = rtController.FullElevationMove(MovementPriority.Manual);
+ break;
+
+ case "THERMAL_CALIBRATE":
+ result = rtController.ThermalCalibrateRadioTelescope(MovementPriority.Manual);
+ break;
+
+ case "STOW":
+ result = rtController.MoveRadioTelescopeToOrientation(MiscellaneousConstants.Stow, MovementPriority.Manual);
+ break;
+
+ case "FULL_CLOCK":
+ result = rtController.MoveRadioTelescopeByXDegrees(new Orientation(360, 0), MovementPriority.Manual);
+ break;
+
+ case "FULL_COUNTER":
+ result = rtController.MoveRadioTelescopeByXDegrees(new Orientation(-360, 0), MovementPriority.Manual);
+ break;
+
+ case "HOME":
+ result = rtController.HomeTelescope(MovementPriority.Manual);
+ break;
+
+ case "HARDWARE_MVMT_SCRIPT":
+ result = rtController.ExecuteHardwareMovementScript(MovementPriority.Manual);
+ break;
+
+ default:
+ // If no command is found, result = invalid
+ result = MovementResult.InvalidCommand;
+ break;
+ }
+
+ // Return based off of movement result
+ if (result != MovementResult.Success)
+ {
+ return new ExecuteTCPCommandResult(result, TCPCommunicationConstants.SCRIPT_ERR + result.ToString());
+ }
+ else
+ {
+ // everything was successful
+ return new ExecuteTCPCommandResult(result);
+ }
+ }
+ else if (command=="STOP_RT")
+ {
+ rtController.RadioTelescope.PLCDriver.InterruptMovementAndWaitUntilStopped();
+
+ return new ExecuteTCPCommandResult(MovementResult.Success, TCPCommunicationConstants.ALL_STOP_ERR);
+
+ }
+ else if (command=="SENSOR_INIT")
+ {
+
+ // Retrieve sensor init values from the comma separated portion of the string
+ string[] splitData = splitCommandString[TCPCommunicationConstants.SENSOR_INIT_VALUES].Split(',');
+
+ var config = rtController.RadioTelescope.SensorNetworkServer.InitializationClient.SensorNetworkConfig;
+
+ // Set all the sensors to their new initialization
+ config.AzimuthTemp1Init = splitData[(int)SensorInitializationEnum.AzimuthTemp].Equals("1");
+ config.ElevationTemp1Init = splitData[(int)SensorInitializationEnum.ElevationTemp].Equals("1");
+ config.AzimuthAccelerometerInit = splitData[(int)SensorInitializationEnum.AzimuthAccelerometer].Equals("1");
+ config.ElevationAccelerometerInit = splitData[(int)SensorInitializationEnum.ElevationAccelerometer].Equals("1");
+ config.CounterbalanceAccelerometerInit = splitData[(int)SensorInitializationEnum.CounterbalanceAccelerometer].Equals("1");
+ config.AzimuthEncoderInit = splitData[(int)SensorInitializationEnum.AzimuthEncoder].Equals("1");
+ config.ElevationEncoderInit = splitData[(int)SensorInitializationEnum.ElevationEncoder].Equals("1");
+
+ // Set the timeout values
+ config.TimeoutDataRetrieval = (int)(double.Parse(splitData[7]) * 1000);
+ config.TimeoutInitialization = (int)(double.Parse(splitData[8]) * 1000);
+
+ // Reboot
+ rtController.RadioTelescope.SensorNetworkServer.RebootSensorNetwork();
+
+ return new ExecuteTCPCommandResult(MovementResult.Success);
+ }
+ else if (command=="REQUEST")
+ {
+ switch (splitCommandString[TCPCommunicationConstants.REQUEST_TYPE])
+ {
+ case "MVMT_DATA":
+ return new ExecuteTCPCommandResult(MovementResult.Success, GetMovementData(version));
+
+ default:
+ return new ExecuteTCPCommandResult(MovementResult.InvalidCommand, TCPCommunicationConstants.INVALID_REQUEST_TYPE + splitCommandString[TCPCommunicationConstants.REQUEST_TYPE]);
+ }
+ }
+ else
+ {
+ // can't find a keyword then we return Invalid Command sent
+ return new ExecuteTCPCommandResult(MovementResult.InvalidCommand, TCPCommunicationConstants.COMMAND_NOT_FOUND + command);
+ }
+ }
+
+ // Version is not found; add new versions here
+ else
+ {
+ return new ExecuteTCPCommandResult(MovementResult.InvalidCommand, TCPCommunicationConstants.VERSION_NOT_FOUND + version);
+ }
+ }
+
+ public ParseTCPCommandResult ParseRLString(string data)
+ {
+ // Break our string into different parts to retrieve respective pieces of command
+ // Based on the command, we will choose what path to follow
+ String[] splitCommandString = data.Trim().Split('|');
+
+ // first check to make sure we have the mininum number of parameters before beginning parsing
+ if (splitCommandString.Length < TCPCommunicationConstants.MIN_NUM_PARAMS)
+ {
+ return new ParseTCPCommandResult(ParseTCPCommandResultEnum.MissingCommandArgs, splitCommandString, TCPCommunicationConstants.MISSING_COMMAND_ARGS);
+ }
+
+ // proceed if valid
+ for (int i = 0; i < splitCommandString.Length; i++)
+ {
+ splitCommandString[i] = splitCommandString[i].Trim();
+ }
+ logger.Info(Utilities.GetTimeStamp() + ": " + String.Join(" ", splitCommandString));
+
+ // Convert version from string to double. This is the first value in our string before the "|" character.
+ // From here we will direct to the appropriate parsing for said version
+ double version = 0.0;
+ bool foundVersion = false;
+ try
+ {
+ version = Double.Parse(splitCommandString[TCPCommunicationConstants.VERSION_NUM]);
+ }
+ catch (Exception e)
+ {
+ String errMessage = TCPCommunicationConstants.VERSION_CONVERSION_ERR + e.Message;
+ return new ParseTCPCommandResult(ParseTCPCommandResultEnum.InvalidVersion, splitCommandString, errMessage);
+
+ }
+ // ensure version exists
+ foreach (string versionNum in TCPCommunicationConstants.ALL_VERSIONS_LIST)
+ {
+ if (versionNum == splitCommandString[TCPCommunicationConstants.VERSION_NUM].Trim())
+ {
+ foundVersion = true;
+ break;
+ }
+ }
+ // if version not found, return false
+ if (!foundVersion)
+ {
+ return new ParseTCPCommandResult(ParseTCPCommandResultEnum.InvalidVersion, splitCommandString, TCPCommunicationConstants.VERSION_NOT_FOUND + version);
+ }
+
+ String command = splitCommandString[TCPCommunicationConstants.COMMAND_TYPE];
+
+ switch (command)
+ {
+ case "ORIENTATION_MOVE":
+ // check to see if we have a valid number of parameters before attempting to parse
+ if (splitCommandString.Length != TCPCommunicationConstants.NUM_ORIENTATION_MOVE_PARAMS)
+ {
+ return new ParseTCPCommandResult(ParseTCPCommandResultEnum.MissingCommandArgs, splitCommandString, TCPCommunicationConstants.MISSING_COMMAND_ARGS + command);
+ }
+ // get azimuth and orientation
+ double absAzimuth = 0.0;
+ double absElevation = 0.0;
+ // Get the number from the AZ and EL portions: e.g AZ 30 --> we want the "30"
+ String[] absAzArr = splitCommandString[TCPCommunicationConstants.ORIENTATION_MOVE_AZ].Split(' ');
+ String[] absElArr = splitCommandString[TCPCommunicationConstants.ORIENTATION_MOVE_EL].Split(' ');
+
+ // If these numbers arent included return error
+ if (absAzArr.Length != 2 || absElArr.Length != 2)
+ {
+ return new ParseTCPCommandResult(ParseTCPCommandResultEnum.MissingCommandArgs, splitCommandString, TCPCommunicationConstants.MISSING_AZ_EL_ARGS);
+ }
+ else
+ {
+ try
+ {
+ absAzimuth = Convert.ToDouble(absAzArr[1]);
+ absElevation = Convert.ToDouble(absElArr[1]);
+ }
+ catch (Exception e)
+ {
+ String errMessage = TCPCommunicationConstants.AZ_EL_CONVERSION_ERR + e.Message;
+ return new ParseTCPCommandResult(ParseTCPCommandResultEnum.InvalidCommandArgs, splitCommandString, errMessage);
+ }
+ splitCommandString[TCPCommunicationConstants.RELATIVE_MOVE_AZ] = absAzArr[1];
+ splitCommandString[TCPCommunicationConstants.RELATIVE_MOVE_EL] = absElArr[1];
+ }
+ return new ParseTCPCommandResult(ParseTCPCommandResultEnum.Success,splitCommandString);
+
+ case "RELATIVE_MOVE":
+ // check to see if we have a valid number of parameters before attempting to parse
+ if (splitCommandString.Length != TCPCommunicationConstants.NUM_RELATIVE_MOVE_PARAMS)
+ {
+ return new ParseTCPCommandResult(ParseTCPCommandResultEnum.MissingCommandArgs, splitCommandString, TCPCommunicationConstants.MISSING_COMMAND_ARGS + command);
+ }
+ // get azimuth and orientation
+ double relativeAzimuth = 0.0;
+ double relativeElevation = 0.0;
+ // Get the number from the AZ and EL portions: e.g AZ 30 --> we want the "30"
+ String[] relativeAzArr = splitCommandString[TCPCommunicationConstants.RELATIVE_MOVE_AZ].Split(' ');
+ String[] relativeElArr = splitCommandString[TCPCommunicationConstants.RELATIVE_MOVE_EL].Split(' ');
+
+ // If these numbers arent included return error
+ if (relativeAzArr.Length != 2 || relativeElArr.Length != 2)
+ {
+ return new ParseTCPCommandResult(ParseTCPCommandResultEnum.MissingCommandArgs, splitCommandString, TCPCommunicationConstants.MISSING_AZ_EL_ARGS);
+ }
+ else
+ {
+ try
+ {
+ relativeAzimuth = Convert.ToDouble(relativeAzArr[1]);
+ relativeElevation = Convert.ToDouble(relativeElArr[1]);
+ }
+ catch (Exception e)
+ {
+ String errMessage = TCPCommunicationConstants.AZ_EL_CONVERSION_ERR + e.Message;
+ return new ParseTCPCommandResult(ParseTCPCommandResultEnum.InvalidCommandArgs, splitCommandString, errMessage);
+ }
+
+ splitCommandString[TCPCommunicationConstants.RELATIVE_MOVE_AZ] = relativeAzArr[1];
+ splitCommandString[TCPCommunicationConstants.RELATIVE_MOVE_EL] = relativeElArr[1];
+ }
+ return new ParseTCPCommandResult(ParseTCPCommandResultEnum.Success, splitCommandString);
+
+ case "SCRIPT":
+ // Check if we have the correct number of params in our string. If not, no need to begin parsing.
+ if (splitCommandString.Length != TCPCommunicationConstants.NUM_SCRIPT_PARAMS)
+ {
+ return new ParseTCPCommandResult(ParseTCPCommandResultEnum.MissingCommandArgs, splitCommandString, TCPCommunicationConstants.MISSING_COMMAND_ARGS + command);
+ }
+
+ string script = splitCommandString[TCPCommunicationConstants.SCRIPT_NAME];
+
+ foreach (string scriptInArr in TCPCommunicationConstants.SCRIPT_NAME_ARRAY)
+ {
+ // if we match a script, we know this script is valid. Return success
+ if (script == scriptInArr) return new ParseTCPCommandResult(ParseTCPCommandResultEnum.Success, splitCommandString);
+ }
+ // if none found, return
+ return new ParseTCPCommandResult(ParseTCPCommandResultEnum.InvalidScript, splitCommandString, TCPCommunicationConstants.SCRIPT_NOT_FOUND + script);
+
+ case "SET_OVERRIDE":
+ // Always check to see if we have our correct number of arguments for command type. Return false if not
+ if (splitCommandString.Length != TCPCommunicationConstants.NUM_SENSOR_OVERRIDE_PARAMS)
+ {
+ return new ParseTCPCommandResult(ParseTCPCommandResultEnum.MissingCommandArgs, splitCommandString, TCPCommunicationConstants.MISSING_COMMAND_ARGS + command);
+ }
+ // If the true false value is not given, we don't know what to do. Return error
+ else if (splitCommandString[TCPCommunicationConstants.DO_OVERRIDE] != "TRUE" &&
+ splitCommandString[TCPCommunicationConstants.DO_OVERRIDE] != "FALSE")
+ {
+ return new ParseTCPCommandResult(ParseTCPCommandResultEnum.MissingCommandArgs, splitCommandString, TCPCommunicationConstants.MISSING_SET_OVERRIDE_ARG + splitCommandString[TCPCommunicationConstants.DO_OVERRIDE]);
+ }
+ else
+ {
+ // see if the sensor requested for override is a valid sensor
+ foreach (string sensor in TCPCommunicationConstants.SENSORS_ARRAY)
+ {
+ if(sensor == splitCommandString[TCPCommunicationConstants.SENSOR_TO_OVERRIDE]) return new ParseTCPCommandResult(ParseTCPCommandResultEnum.Success, splitCommandString);
+ }
+ return new ParseTCPCommandResult(ParseTCPCommandResultEnum.InvalidCommandArgs, splitCommandString, TCPCommunicationConstants.INVALID_SENSOR_OVERRIDE + splitCommandString[TCPCommunicationConstants.SENSOR_TO_OVERRIDE]);
+ }
+
+ case "STOP_RT":
+ break;
+ case "SENSOR_INIT":
+ // Check for valid number of parameters before continuing parsing
+ if (splitCommandString.Length != TCPCommunicationConstants.NUM_SENSOR_INIT_PARAMS)
+ {
+ return new ParseTCPCommandResult(ParseTCPCommandResultEnum.MissingCommandArgs, splitCommandString, TCPCommunicationConstants.MISSING_COMMAND_ARGS + command);
+ }
+
+ // Retrieve sensor init values from the comma separated portion of the string
+ string[] splitData = splitCommandString[TCPCommunicationConstants.SENSOR_INIT_VALUES].Split(',');
+ // there should be 9, if not, no bueno
+ if (splitData.Length != 9) return new ParseTCPCommandResult(ParseTCPCommandResultEnum.MissingCommandArgs, splitCommandString,TCPCommunicationConstants.MISSING_SENSOR_INIT_ARGS);
+ else { return new ParseTCPCommandResult(ParseTCPCommandResultEnum.Success, splitCommandString); }
+
+
+ case "REQUEST":
+ if (splitCommandString.Length != TCPCommunicationConstants.NUM_REQUEST_PARAMS)
+ {
+ return new ParseTCPCommandResult(ParseTCPCommandResultEnum.MissingCommandArgs, splitCommandString, TCPCommunicationConstants.MISSING_COMMAND_ARGS + command);
+ }
+
+ switch (splitCommandString[TCPCommunicationConstants.REQUEST_TYPE])
+ {
+ case "MVMT_DATA":
+ return new ParseTCPCommandResult(ParseTCPCommandResultEnum.Success, splitCommandString);
+
+ default:
+ return new ParseTCPCommandResult(ParseTCPCommandResultEnum.InvalidRequestType, splitCommandString, TCPCommunicationConstants.INVALID_REQUEST_TYPE + splitCommandString[TCPCommunicationConstants.REQUEST_TYPE]);
+ }
+ break;
+
+ case "RESET_MCU_BIT":
+ if (splitCommandString.Length != TCPCommunicationConstants.NUM_MCU_RESET_PARAMS)
+ {
+ return new ParseTCPCommandResult(ParseTCPCommandResultEnum.MissingCommandArgs, splitCommandString, TCPCommunicationConstants.MISSING_COMMAND_ARGS);
+ }
+ else if (version < 1.1)
+ {
+ return new ParseTCPCommandResult(ParseTCPCommandResultEnum.InvalidVersion, splitCommandString, TCPCommunicationConstants.INVALID_VERSION);
+ }
+ else
+ {
+ return new ParseTCPCommandResult(ParseTCPCommandResultEnum.Success, splitCommandString);
+ }
+ break;
+ // if we get here, command type not found
+ default:
+ return new ParseTCPCommandResult(ParseTCPCommandResultEnum.InvalidCommandType, splitCommandString, TCPCommunicationConstants.COMMAND_NOT_FOUND);
+
+ }
+
+ // else all parsing was successful, return and inform client
+ return new ParseTCPCommandResult(ParseTCPCommandResultEnum.Success, splitCommandString);
+ }
+
+ ///
+ /// Util method to handle error checking with strem.read/writes
+ ///
+ /// What you are sending back to the client
+ /// Data stream to send the data back to the client
+ /// Boolean value that represents whether or not the data should be encrypted before sending
+ public void writeBackToClient(string text, NetworkStream stream, bool encrypted)
+ {
+ byte[] textToBytes;
+
+ if (encrypted)
+ {
+ textToBytes = Encoding.ASCII.GetBytes(AES.Encrypt(text, AESConstants.KEY, AESConstants.IV));
+ }
+ else
+ {
+ textToBytes = Encoding.ASCII.GetBytes(text);
+ }
+
+ try
+ {
+ stream.Write(textToBytes, 0, textToBytes.Length);
+ }
+ catch(Exception e)
+ {
+ logger.Error("An error occured when attempting to write back to the client: " + e.Message);
+ }
+ }
+
+ public int readFromStream(NetworkStream stream, Byte[] buffer)
+ {
+ try
+ {
+ return stream.Read(buffer, 0, buffer.Length);
+ }
+ catch(Exception e)
+ {
+ logger.Error("An error occured reaading data from the client: " + e.Message);
+
+ }
+ return 0;
+
+ }
+
+
+ ///
+ /// These ETA functions are used to calculate the estimated time a movement should take, and in turn sent back to the mobile app in order to display a progress bar.
+ ///
+ ///
+ ///
+ public int AbsoluteMovementETA(Orientation targetOrientation)
+ {
+ // distance is degrees to steps for az/el
+ // time is in milliseconds
+ int EL_Speed = ConversionHelper.DPSToSPS(ConversionHelper.RPMToDPS(0.6), MotorConstants.GEARING_RATIO_ELEVATION);
+ int AZ_Speed = ConversionHelper.DPSToSPS(ConversionHelper.RPMToDPS(0.6), MotorConstants.GEARING_RATIO_AZIMUTH);
+
+ Orientation currentOrientation = rtController.GetCurrentOrientation();
+ int positionTranslationAZ = ConversionHelper.DegreesToSteps(targetOrientation.Azimuth - currentOrientation.Azimuth, MotorConstants.GEARING_RATIO_AZIMUTH);
+ int positionTranslationEL = ConversionHelper.DegreesToSteps((targetOrientation.Elevation - currentOrientation.Elevation), MotorConstants.GEARING_RATIO_ELEVATION);
+
+ int timeToMoveEl = MCUManager.EstimateMovementTime(EL_Speed, positionTranslationEL);
+ int timeToMoveAz = MCUManager.EstimateMovementTime(AZ_Speed, positionTranslationAZ);
+
+ // return the greater of the two times (we have to wait for longest mvmt)
+ int timeToMove = timeToMoveEl > timeToMoveAz ? timeToMoveEl : timeToMoveAz;
+ return timeToMove;
+
+ }
+
+ public int RelativeMovementETA(Orientation movingBy)
+ {
+ // distance is degrees to steps for az/el
+ // time is in milliseconds
+ int EL_Speed = ConversionHelper.DPSToSPS(ConversionHelper.RPMToDPS(0.6), MotorConstants.GEARING_RATIO_ELEVATION);
+ int AZ_Speed = ConversionHelper.DPSToSPS(ConversionHelper.RPMToDPS(0.6), MotorConstants.GEARING_RATIO_AZIMUTH);
+
+ int positionTranslationAZ = ConversionHelper.DegreesToSteps(movingBy.Azimuth, MotorConstants.GEARING_RATIO_AZIMUTH);
+ int positionTranslationEL = ConversionHelper.DegreesToSteps(movingBy.Elevation, MotorConstants.GEARING_RATIO_ELEVATION);
+
+ int timeToMoveEl = MCUManager.EstimateMovementTime(EL_Speed, positionTranslationEL);
+ int timeToMoveAz = MCUManager.EstimateMovementTime(AZ_Speed, positionTranslationAZ);
+
+ // return the greater of the two times (we have to wait for longest mvmt)
+ int timeToMove = timeToMoveEl > timeToMoveAz ? timeToMoveEl : timeToMoveAz;
+ return timeToMove;
+ }
+
+ public int ScriptETA(string scriptType)
+ {
+ switch (scriptType.Trim())
+ {
+ case "DUMP":
+ return 0;
+
+ case "FULL_EV":
+ return AbsoluteMovementETA(new Orientation(0, 90)) + RelativeMovementETA(new Orientation(0, -90));
+
+ case "THERMAL_CALIBRATE":
+ return 0;
+
+ case "STOW":
+ return AbsoluteMovementETA(new Orientation(0, 90));
+
+ case "FULL_CLOCK":
+ return AbsoluteMovementETA(new Orientation(360, 0));
+
+ case "FULL_COUNTER":
+ return AbsoluteMovementETA(new Orientation(-360,0));
+
+ case "HOME":
+ return AbsoluteMovementETA(new Orientation(0, 0));
+
+ case "HARDWARE_MVMT_SCRIPT":
+ return 0;
+
+ // If no command is found, invalid script. Return -1
+ default:
+ return -1;
+ }
+ return -1;
+ }
+ ///
+ /// Used for when the mobile app sends a command for REQUEST | MVMT_DATA. This will specify the current location of the telescope, and whether or not
+ /// it is currently moving.
+ ///
+ ///
+ public string GetMovementData(double versionNum)
+ {
+ Orientation currentPos = rtController.GetCurrentOrientation();
+ string currentlyMoving = rtController.RadioTelescope.PLCDriver.MotorsCurrentlyMoving().ToString().ToUpper();
+ string sendBack = "MOVING: " + currentlyMoving + " | " + "AZ: " + currentPos.Azimuth + " | " + "EL: " + currentPos.Elevation;
+
+ // Send back MCU data if TCP version is 1.1 or greater
+ if (versionNum >= 1.1)
+ {
+ sendBack += " | BIT_FLIPPED: " + Convert.ToString(rtController.RadioTelescope.PLCDriver.CheckMCUErrors().Count > 0).ToUpper();
+ }
+
+ return sendBack;
+ }
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/Communications/SNSMessage.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/Communications/SNSMessage.cs
new file mode 100644
index 00000000..5512189a
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/Communications/SNSMessage.cs
@@ -0,0 +1,50 @@
+using System;
+using System.Collections.Generic;
+using ControlRoomApplication.Entities;
+using Amazon;
+using Amazon.SimpleNotificationService;
+using Amazon.SimpleNotificationService.Model;
+using ControlRoomApplication.Constants;
+
+namespace ControlRoomApplication.Controllers
+{
+ class SNSMessage
+ {
+ public static void sendMessage(User user, MessageTypeEnum type)
+ {
+
+ if (user.first_name == "control")
+ {
+ return;
+ }
+
+ AmazonSimpleNotificationServiceClient snsClient = new AmazonSimpleNotificationServiceClient(AWSConstants.SNS_ACCESS_KEY, AWSConstants.SNS_SECRET_ACCESS_KEY, Amazon.RegionEndpoint.USEast1);
+
+ PublishRequest pubRequest = new PublishRequest();
+
+ // get the message that corresponds to the type of notification
+ pubRequest.Message = MessageTypeExtension.GetDescription(type);
+
+ // sending sms message
+ if (user._Notification_Type == NotificationTypeEnum.SMS || user._Notification_Type == NotificationTypeEnum.ALL)
+ {
+ // we need to have +1 on the beginning of the number in order to send
+ if (user.phone_number.Substring(0, 2) != "+1")
+ {
+ pubRequest.PhoneNumber = "+1" + user.phone_number;
+ }
+ else
+ {
+ pubRequest.PhoneNumber = user.phone_number;
+ }
+
+ PublishResponse pubResponse = snsClient.Publish(pubRequest);
+ Console.WriteLine(pubResponse.MessageId);
+ }
+ }
+ }
+}
+
+
+
+
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/Communications/SendAttachmentHelper.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/Communications/SendAttachmentHelper.cs
new file mode 100644
index 00000000..67484f84
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/Communications/SendAttachmentHelper.cs
@@ -0,0 +1,43 @@
+/// A Lifesaver(tm): https://colinmackay.scot/2011/11/10/sending-more-than-a-basic-email-with-amazon-ses/
+/// Modified for running in .NET version > .NET 4.5
+
+using System;
+using System.IO;
+using System.Net.Mail;
+using System.Reflection;
+
+namespace ControlRoomApplication.Controllers.Communications
+{
+ public static class SendAttachmentHelper
+ {
+ private static readonly BindingFlags Flags = BindingFlags.Instance | BindingFlags.NonPublic;
+ private static readonly ConstructorInfo _mailWriterConstructor;
+ private static readonly MethodInfo _sendMethod;
+ private static readonly MethodInfo _closeMethod;
+
+ static SendAttachmentHelper()
+ {
+ Assembly systemAssembly = typeof(SmtpClient).Assembly;
+ Type mailWriterType = systemAssembly.GetType("System.Net.Mail.MailWriter");
+
+ _mailWriterConstructor = mailWriterType.GetConstructor(Flags, null, new[] { typeof(Stream) }, null);
+
+ _sendMethod = typeof(MailMessage).GetMethod("Send", Flags);
+
+ _closeMethod = mailWriterType.GetMethod("Close", Flags);
+ }
+
+ public static MemoryStream ConvertMailMessageToMemoryStream(MailMessage message)
+ {
+ using (MemoryStream memoryStream = new MemoryStream())
+ {
+ object mailWriter = _mailWriterConstructor.Invoke(new object[] { memoryStream });
+
+ _sendMethod.Invoke(message, Flags, null, new[] { mailWriter, true, true }, null);
+ _closeMethod.Invoke(mailWriter, Flags, null, new object[] { }, null);
+
+ return memoryStream;
+ }
+ }
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/ControlRoomController/ControlRoomController.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/ControlRoomController/ControlRoomController.cs
index a010387d..fcbdee3d 100644
--- a/ControlRoomApplication/ControlRoomApplication/Controllers/ControlRoomController/ControlRoomController.cs
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/ControlRoomController/ControlRoomController.cs
@@ -1,6 +1,10 @@
using System;
using System.Threading;
using ControlRoomApplication.Entities;
+using ControlRoomApplication.Database;
+using ControlRoomApplication.Controllers.Communications;
+using ControlRoomApplication.Util;
+
namespace ControlRoomApplication.Controllers
{
@@ -12,10 +16,13 @@ public class ControlRoomController
private Thread WeatherMonitoringThread;
private bool KeepWeatherMonitoringThreadAlive;
+ // Weather Station override
+ //public bool weatherStationOverride = false;
+
public ControlRoomController(ControlRoom controlRoom)
{
ControlRoom = controlRoom;
- WeatherMonitoringThread = new Thread(new ThreadStart(WeatherMonitoringRoutine));
+ WeatherMonitoringThread = new Thread( new ThreadStart( WeatherMonitoringRoutine ) ) { Name = "Weather Monitoring Routine" };
KeepWeatherMonitoringThreadAlive = false;
}
@@ -76,13 +83,70 @@ public void WeatherMonitoringRoutine()
{
while (KeepWeatherMonitoringThreadAlive)
{
- // logger.Info("[ControlRoomController] Weather station reading: " + ControlRoom.WeatherStation.CurrentWindSpeedMPH.ToString() + " MPH wind speeds.");
- if (!ControlRoom.WeatherStation.CurrentWindSpeedIsAllowable)
+ Sensor currentSensor = ControlRoom.RTControllerManagementThreads[0].Sensors.Find(i => i.Item == SensorItemEnum.WIND);
+ int windSpeedStatus = ControlRoom.WeatherStation.CurrentWindSpeedStatus;
+
+ // The Wind Speed has triggered an Alarm Status
+ if (windSpeedStatus == 2)
{
- logger.Info("[ControlRoomController] Wind speeds were too high: " + ControlRoom.WeatherStation.CurrentWindSpeedMPH);
+ logger.Info(Utilities.GetTimeStamp() + ": [ControlRoomController] Wind speeds were too high: " + ControlRoom.WeatherStation.CurrentWindSpeedMPH);
+
+ // Overriding the status warning if override is true
+ if (!ControlRoom.weatherStationOverride)
+ {
+ currentSensor.Status = SensorStatusEnum.ALARM;
+
+ pushNotification.sendToAllAdmins("WARNING: WEATHER STATION", "Wind speeds are too high: " + ControlRoom.WeatherStation.CurrentWindSpeedMPH);
+ EmailNotifications.sendToAllAdmins("WARNING: WEATHER STATION", "Wind speeds are too high: " + ControlRoom.WeatherStation.CurrentWindSpeedMPH);
+ }
+ DatabaseOperations.AddSensorStatusData(SensorStatus.Generate(SensorStatusEnum.WARNING, SensorStatusEnum.NORMAL, SensorStatusEnum.NORMAL, SensorStatusEnum.ALARM, currentSensor.Status));
+ //ControlRoom.RTControllerManagementThreads[0].checkCurrentSensorAndOverrideStatus();
+
+ /*
+ //shut down telescopes
+ foreach (RadioTelescopeController telescopeController in ControlRoom.RadioTelescopeControllers)
+ {
+ // change the sensor status in our Radio Telescope Controller Management Thread
+ //int id = ControlRoom.RadioTelescopes.Find(i => i.WeatherStation == ControlRoom.WeatherStation).Id;
+ //ControlRoom.RTControllerManagementThreads[0].Sensors.Add(new Sensor(SensorItemEnum.WIND_SPEED, SensorStatus.ALARM));
+ //ControlRoom.RTControllerManagementThreads[0].checkCurrentSensorAndOverrideStatus();
+ }
+ */
}
+ // The Wind Speed has triggered a Warning Status
+ else if(windSpeedStatus == 1)
+ {
+ logger.Info(Utilities.GetTimeStamp() + ": [ControlRoomController] Wind speeds are in Warning Range: " + ControlRoom.WeatherStation.CurrentWindSpeedMPH);
+
+
+ // Overriding the status warning if override is true
+ if (!ControlRoom.weatherStationOverride)
+ {
+ currentSensor.Status = SensorStatusEnum.WARNING;
+
+ pushNotification.sendToAllAdmins("WARNING: WEATHER STATION", "Wind speeds are in Warning Range: " + ControlRoom.WeatherStation.CurrentWindSpeedMPH);
+ EmailNotifications.sendToAllAdmins("WARNING: WEATHER STATION", "Wind speeds are in Warning Range: " + ControlRoom.WeatherStation.CurrentWindSpeedMPH);
+ }
+ DatabaseOperations.AddSensorStatusData(SensorStatus.Generate(SensorStatusEnum.WARNING, SensorStatusEnum.NORMAL, SensorStatusEnum.NORMAL, SensorStatusEnum.ALARM, currentSensor.Status));
+ }
+ else if (windSpeedStatus == 0)
+ {
+ //logger.Info(Utilities.GetTimeStamp() + ": [ControlRoomController] Wind speeds are in a Safe State: " + ControlRoom.WeatherStation.CurrentWindSpeedMPH);
+ currentSensor.Status = SensorStatusEnum.NORMAL;
+ DatabaseOperations.AddSensorStatusData(SensorStatus.Generate(SensorStatusEnum.WARNING, SensorStatusEnum.NORMAL, SensorStatusEnum.NORMAL, SensorStatusEnum.ALARM, currentSensor.Status));
+ }
+
+ /*
+ else if(currentSensor != null && currentSensor.Status == SensorStatus.ALARM) {
+
+ //change the status
+ currentSensor.Status = SensorStatus.NORMAL;
+ logger.Info(Utilities.GetTimeStamp() + ": Wind speed sensor back in normal range.");
+ }*/
+
+ //logger.Info(Utilities.GetTimeStamp() + ": Current wind speed is: " + ControlRoom.WeatherStation.GetWindSpeed());
- Thread.Sleep(1000);
+ Thread.Sleep(1000);
}
}
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/ControlRoomController/RadioTelescopeControllerManagementThread.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/ControlRoomController/RadioTelescopeControllerManagementThread.cs
index 2d16e646..021f8589 100644
--- a/ControlRoomApplication/ControlRoomApplication/Controllers/ControlRoomController/RadioTelescopeControllerManagementThread.cs
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/ControlRoomController/RadioTelescopeControllerManagementThread.cs
@@ -3,6 +3,13 @@
using System.Collections.Generic;
using ControlRoomApplication.Entities;
using ControlRoomApplication.Database;
+using System.Net;
+using ControlRoomApplication.Controllers.Communications;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System.IO;
+using ControlRoomApplication.Util;
+using ControlRoomApplication.Controllers.PLCCommunication.PLCDrivers.MCUManager;
+using ControlRoomApplication.Controllers.PLCCommunication.PLCDrivers.MCUManager.Enumerations;
namespace ControlRoomApplication.Controllers
{
@@ -13,12 +20,28 @@ public class RadioTelescopeControllerManagementThread
public RadioTelescopeController RTController { get; private set; }
public Appointment AppointmentToDisplay { get; private set; }
- private Thread ManagementThread;
+ public Thread ManagementThread;
private Mutex ManagementMutex;
private volatile bool KeepThreadAlive;
private volatile bool InterruptAppointmentFlag;
private Orientation _NextObjectiveOrientation;
+ public RemoteListener TCPListener { get; }
+
+ public List ActiveOverrides;
+ public List Sensors;
+
+ private bool OverallSensorStatus;
+
+ private bool endAppt = false;
+
+ Appointment OldAppointment = new Appointment();
+ Appointment NextAppointment = new Appointment();
+
+ bool safeTel = false;
+
+ private int timeoutCounter = 0;
+
public Orientation NextObjectiveOrientation
{
get
@@ -70,6 +93,17 @@ public RadioTelescopeControllerManagementThread(RadioTelescopeController control
KeepThreadAlive = false;
_NextObjectiveOrientation = null;
InterruptAppointmentFlag = false;
+
+ ActiveOverrides = new List();
+ Sensors = new List();
+ OverallSensorStatus = true;
+
+ Sensors.Add(new Sensor(SensorItemEnum.WIND, SensorStatusEnum.NORMAL));
+
+ // Commented out because we will not be using this functionality in the future.
+ // We will switch to connecting to a server on the cloud
+ // Kate Kennelly 2/14/2020
+ // TCPListener = new RemoteListener(8090, IPAddress.Parse("10.127.7.112"), controller);
}
public bool Start()
@@ -78,6 +112,8 @@ public bool Start()
try
{
+ // Sensors.Add(new Sensor(SensorItemEnum.WIND_SPEED, SensorStatusEnum.NORMAL));
+
ManagementThread.Start();
}
catch (Exception e)
@@ -137,20 +173,34 @@ public void InterruptOnce()
private void SpinRoutine()
{
bool KeepAlive = KeepThreadAlive;
-
+
while (KeepAlive)
{
- Appointment NextAppointment = WaitForNextAppointment();
+ NextAppointment = WaitForNextAppointment();
+
+ //Compares the ID of each appointment to see if they have changed
+ if (NextAppointment != null && NextAppointment.Equals(OldAppointment))
+ {
+ logger.Info(Utilities.GetTimeStamp() + ": Waiting for next Appointment");
+ }
+
if (NextAppointment != null)
{
- logger.Info("Starting appointment...");
+ logger.Info(Utilities.GetTimeStamp() + ": Starting appointment...");
+ endAppt = false;
// Calibrate telescope
- if (NextAppointment.Type != AppointmentTypeEnum.FREE_CONTROL)
+ if (NextAppointment._Type != AppointmentTypeEnum.FREE_CONTROL)
{
- logger.Info("Calibrating RadioTelescope");
- RTController.CalibrateRadioTelescope();
+ logger.Info(Utilities.GetTimeStamp() + ": Thermal Calibrating RadioTelescope");
+ RTController.ThermalCalibrateRadioTelescope(MovementPriority.Appointment);
+
+ // If the temperature is low and there's precipitation, dump the dish
+ if (RTController.RadioTelescope.WeatherStation.GetOutsideTemp() <= 40.00 && RTController.RadioTelescope.WeatherStation.GetTotalRain() > 0.00)
+ {
+ RTController.SnowDump(MovementPriority.Appointment);
+ }
}
// Create movement thread
@@ -159,36 +209,53 @@ private void SpinRoutine()
Name = "RTControllerIntermediateThread (ID=" + RadioTelescopeID.ToString() + ")"
};
- // Start SpectraCyber
- StartReadingData(NextAppointment);
+ // Start SpectraCyber if the next appointment is NOT an appointment created by the control form
+ // This is to allow for greater control of the spectra cyber output from the control form
+ if(NextAppointment._Type != AppointmentTypeEnum.FREE_CONTROL)
+ StartReadingData(NextAppointment);
// Start movement thread
AppointmentMovementThread.Start();
- // End PLC thread & SpectraCyber
- AppointmentMovementThread.Join();
- StopReadingRFData();
-
- // Stow Telescope
- EndAppointment();
+ if(NextAppointment._Type != AppointmentTypeEnum.FREE_CONTROL)
+ {
+ // End PLC thread & SpectraCyber
+ AppointmentMovementThread.Join();
+ StopReadingRFData();
+ // Stow Telescope
+ EndAppointment();
+ }
+ else
+ {
+ while (endAppt == false)
+ {
+ ;
+ }
+ }
- logger.Info("Appointment completed.");
+ logger.Info(Utilities.GetTimeStamp() + ": Appointment completed.");
}
else
{
if (InterruptAppointmentFlag)
{
- logger.Info("Appointment interrupted in loading routine.");
+ logger.Info(Utilities.GetTimeStamp() + ": Appointment interrupted in loading routine.");
ManagementMutex.WaitOne();
InterruptAppointmentFlag = false;
ManagementMutex.ReleaseMutex();
}
- logger.Info("Appointment does not have an orientation associated with it.");
+ if (NextAppointment != null && NextAppointment.Equals(OldAppointment))
+ {
+ logger.Info(Utilities.GetTimeStamp() + ": Appointment does not have an orientation associated with it.");
+
+ }
}
KeepAlive = KeepThreadAlive;
+ OldAppointment = NextAppointment;
+
Thread.Sleep(100);
}
}
@@ -201,9 +268,13 @@ private void SpinRoutine()
/// An appointment object that is next in chronological order and is less than 10 minutes away from starting.
private Appointment WaitForNextAppointment()
{
- Appointment NextAppointment;
- while ((NextAppointment = DatabaseOperations.GetNextAppointment(RadioTelescopeID)) == null)
+ bool waiting = false;
+ Appointment NextAppointment = DatabaseOperations.GetNextAppointment(RadioTelescopeID);
+ TimeSpan diff;
+ while (NextAppointment != null && (diff = NextAppointment.start_time - DateTime.UtcNow).TotalMinutes > 1)
{
+ NextAppointment = DatabaseOperations.GetNextAppointment(RadioTelescopeID);
+
if (InterruptAppointmentFlag || (!KeepThreadAlive))
{
return null;
@@ -211,21 +282,15 @@ private Appointment WaitForNextAppointment()
// Delay between checking database for new appointments
Thread.Sleep(100);
+
+ if(!waiting) logger.Info(Utilities.GetTimeStamp() + ": Waiting for the next appointment to be within 1 minutes.");
+ waiting = true;
}
- logger.Info("Waiting for the next appointment to be within 10 minutes.");
- TimeSpan diff;
- while ((diff = NextAppointment.StartTime - DateTime.UtcNow).TotalMinutes > 1)
+ if (NextAppointment != null && NextAppointment.Equals(OldAppointment))
{
- if (InterruptAppointmentFlag || (!KeepThreadAlive))
- {
- return null;
- }
-
- // Wait more
+ logger.Info(Utilities.GetTimeStamp() + ": The next appointment is now within the correct timeframe.");
}
-
- logger.Info("The next appointment is now within the correct timeframe.");
AppointmentToDisplay = NextAppointment;
return NextAppointment;
}
@@ -238,104 +303,173 @@ private Appointment WaitForNextAppointment()
/// The appointment that is currently running.
private void PerformRadioTelescopeMovement(Appointment NextAppointment)
{
- NextAppointment.Status = AppointmentStatusEnum.IN_PROGRESS;
+ NextAppointment._Status = AppointmentStatusEnum.IN_PROGRESS;
DatabaseOperations.UpdateAppointment(NextAppointment);
- logger.Info("Appointment Type: " + NextAppointment.Type);
+ // send message to appointment's user
+ SNSMessage.sendMessage(NextAppointment.User, MessageTypeEnum.APPOINTMENT_STARTED);
+
+
+ logger.Info(Utilities.GetTimeStamp() + ": Appointment _Type: " + NextAppointment._Type);
// Loop through each second or minute of the appointment (depending on appt type)
- TimeSpan length = NextAppointment.EndTime - NextAppointment.StartTime;
- double duration = NextAppointment.Type == AppointmentTypeEnum.FREE_CONTROL ? length.TotalSeconds : length.TotalMinutes;
+ TimeSpan length = NextAppointment.end_time - NextAppointment.start_time;
+ double duration = NextAppointment._Type == AppointmentTypeEnum.FREE_CONTROL ? length.TotalSeconds : length.TotalMinutes;
for (int i = 0; i <= (int) duration; i++)
{
- // Get orientation for current datetime
- DateTime datetime = NextAppointment.Type == AppointmentTypeEnum.FREE_CONTROL ? NextAppointment.StartTime.AddSeconds(i) : NextAppointment.StartTime.AddMinutes(i);
- NextObjectiveOrientation = RTController.CoordinateController.CalculateOrientation(NextAppointment, datetime);
-
- // Wait for datetime
- while (DateTime.UtcNow < datetime)
+ // before we move, check to see if it is safe
+ if (checkCurrentSensorAndOverrideStatus())
{
+
+ // Get orientation for current datetime
+ DateTime datetime = NextAppointment._Type == AppointmentTypeEnum.FREE_CONTROL ? NextAppointment.start_time.AddSeconds(i) : NextAppointment.start_time.AddMinutes(i);
+ NextObjectiveOrientation = RTController.CoordinateController.CalculateOrientation(NextAppointment, datetime);
+
+ // Wait for datetime
+ while (DateTime.UtcNow < datetime)
+ {
+ if (InterruptAppointmentFlag)
+ {
+ logger.Info(Utilities.GetTimeStamp() + ": Interrupted appointment [" + NextAppointment.Id.ToString() + "] at " + DateTime.Now.ToString());
+ break;
+ }
+
+ //logger.Debug(datetime.ToString() + " vs. " + DateTime.UtcNow.ToString());
+ Thread.Sleep(1000);
+ }
+
if (InterruptAppointmentFlag)
{
- logger.Info("Interrupted appointment [" + NextAppointment.Id.ToString() + "] at " + DateTime.Now.ToString());
break;
}
- //logger.Debug(datetime.ToString() + " vs. " + DateTime.UtcNow.ToString());
- Thread.Sleep(1000);
- }
-
- if (InterruptAppointmentFlag)
- {
- break;
- }
-
// Move to orientation
if (NextObjectiveOrientation != null)
{
- if (NextObjectiveOrientation.Azimuth < 0 || NextObjectiveOrientation.Elevation < 0)
+ // Kate - removed the check for azumith < 0 in the below if statement due to Todd's request
+ // Reason being, we should not have an azimuth below 0 be given to us. That check is in the
+ // method calling this!
+ if (NextObjectiveOrientation.Elevation < 0)
{
- logger.Warn("Invalid Appt: Az = " + NextObjectiveOrientation.Azimuth + ", El = " + NextObjectiveOrientation.Elevation);
+ logger.Warn(Utilities.GetTimeStamp() + ": Invalid Appt: Az = " + NextObjectiveOrientation.Azimuth + ", El = " + NextObjectiveOrientation.Elevation);
InterruptAppointmentFlag = true;
break;
}
- logger.Info("Moving to Next Objective: Az = " + NextObjectiveOrientation.Azimuth + ", El = " + NextObjectiveOrientation.Elevation);
- RTController.MoveRadioTelescopeToOrientation(NextObjectiveOrientation);
+ logger.Info(Utilities.GetTimeStamp() + ": Moving to Next Objective: Az = " + NextObjectiveOrientation.Azimuth + ", El = " + NextObjectiveOrientation.Elevation);
+
+ MovementResult apptMovementResult = RTController.MoveRadioTelescopeToOrientation(NextObjectiveOrientation, MovementPriority.Appointment);
+
+ // If the movement result was anything other than success, it means the movement failed and something is wrong with
+ // the hardware.
+ // TODO: Talk to Todd about thresholds for this. (issue #388) Right now, it is cancelling the appointment if the movement
+ // returns back any single error. See the MovementResult enum for a list of the different errors.
+ if (apptMovementResult == MovementResult.TimedOut)
+ {
+ timeoutCounter++;
+ }
+ else if(apptMovementResult == MovementResult.Success)
+ {
+ timeoutCounter = 0;
+ }
+
+ if (apptMovementResult != MovementResult.Success && timeoutCounter >= 5)
+ {
+ logger.Info($"{Utilities.GetTimeStamp()}: Appointment movement FAILED with the following error message: {apptMovementResult.ToString()}");
+ InterruptAppointmentFlag = true;
+ }
- // Wait until telescope reaches destination
- Orientation currentOrientation;
- do
- {
if (InterruptAppointmentFlag)
{
break;
}
+
+ Thread.Sleep(100);
- //currentOrientation = RTController.GetCurrentOrientation();
- //logger.Info("Progress Towards Objective: Az = " + currentOrientation.Azimuth + ", El = " + currentOrientation.Elevation);
- Thread.Sleep(100);
+ NextObjectiveOrientation = null;
}
- while (!RTController.finished_exicuting_move());
-
- NextObjectiveOrientation = null;
+ } else
+ {
+ logger.Info(Utilities.GetTimeStamp() + ": Telescope stopped movement.");
+ i--;
}
}
+ // Set email sender
+ string emailSender = "noreply@ycpradiotelescope.com";
+
if (InterruptAppointmentFlag)
{
- logger.Info("Interrupted appointment [" + NextAppointment.Id.ToString() + "] at " + DateTime.Now.ToString());
- NextAppointment.Status = AppointmentStatusEnum.CANCELLED;
+ logger.Info(Utilities.GetTimeStamp() + ": Interrupted appointment [" + NextAppointment.Id.ToString() + "] at " + DateTime.Now.ToString());
+ NextAppointment._Status = AppointmentStatusEnum.CANCELED;
DatabaseOperations.UpdateAppointment(NextAppointment);
NextObjectiveOrientation = null;
InterruptAppointmentFlag = false;
+
+ // send message to appointment's user
+ SNSMessage.sendMessage(NextAppointment.User, MessageTypeEnum.APPOINTMENT_CANCELLED);
+
+ string subject = MessageTypeExtension.GetDescription(MessageTypeEnum.APPOINTMENT_CANCELLED);
+ string text = MessageTypeExtension.GetDescription(MessageTypeEnum.APPOINTMENT_CANCELLED);
+
+ EmailNotifications.sendToUser(NextAppointment.User, subject, text, emailSender);
}
else
{
- NextAppointment.Status = AppointmentStatusEnum.COMPLETED;
+ NextAppointment._Status = AppointmentStatusEnum.COMPLETED;
DatabaseOperations.UpdateAppointment(NextAppointment);
- }
- DatabaseOperations.UpdateAppointment(NextAppointment);
+ // send message to appointment's user
+ SNSMessage.sendMessage(NextAppointment.User, MessageTypeEnum.APPOINTMENT_COMPLETION);
+
+ // Gather up email data
+ string subject = MessageTypeExtension.GetDescription(MessageTypeEnum.APPOINTMENT_COMPLETION);
+ string text = MessageTypeExtension.GetDescription(MessageTypeEnum.APPOINTMENT_COMPLETION);
+ string attachmentPath = "";
+
+ string fname = System.DateTime.Now.ToString("yyyyMMddHHmmss");
+ string currentPath = AppDomain.CurrentDomain.BaseDirectory;
+
+ List data = (List)NextAppointment.RFDatas;
+ try
+ {
+ attachmentPath = Path.Combine(currentPath, $"{fname}.csv");
+ DataToCSV.ExportToCSV(data, fname);
+ }
+ catch (Exception e)
+ {
+ Console.Out.WriteLine($"Could not write data! Error: {e}");
+ }
+
+ EmailNotifications.sendToUser(NextAppointment.User, subject, text, emailSender, attachmentPath, true);
+
+ // Clean up after yourself, otherwise you'll just fill up our storage space
+ DataToCSV.DeleteCSVFileWhenDone(attachmentPath);
+ }
}
///
/// Ends an appointment by returning the RT to the stow position.
///
- private void EndAppointment()
+ public void EndAppointment()
{
- logger.Info("Ending Appointment");
- RTController.MoveRadioTelescopeToOrientation(new Orientation(0, 90));
+ logger.Info(Utilities.GetTimeStamp() + ": Ending Appointment");
+ endAppt = true;
+ MovementResult result = RTController.MoveRadioTelescopeToOrientation(new Orientation(0, 90), MovementPriority.Appointment);
+ if (result != MovementResult.Success)
+ {
+ logger.Error("Stowing telescope failed with message " + result);
+ }
}
///
/// Calls the SpectraCyber controller to start the SpectraCyber readings.
///
- private void StartReadingData(Appointment appt)
+ public void StartReadingData(Appointment appt)
{
- logger.Info("Starting Reading of RFData");
+ logger.Info(Utilities.GetTimeStamp() + ": Starting Reading of RFData");
RTController.RadioTelescope.SpectraCyberController.SetApptConfig(appt);
- RTController.RadioTelescope.SpectraCyberController.StartScan();
+ RTController.RadioTelescope.SpectraCyberController.StartScan(appt);
}
///
@@ -343,26 +477,48 @@ private void StartReadingData(Appointment appt)
///
private void StopReadingRFData()
{
- logger.Info("Stoping Reading of RTData");
+ logger.Info(Utilities.GetTimeStamp() + ": Stoping Reading of RTData");
RTController.RadioTelescope.SpectraCyberController.StopScan();
RTController.RadioTelescope.SpectraCyberController.RemoveActiveAppointmentID();
RTController.RadioTelescope.SpectraCyberController.SetSpectraCyberModeType(SpectraCyberModeTypeEnum.UNKNOWN);
}
- public static int IndexOf(List ThreadList, RadioTelescope RadioTelescope)
+ ///
+ /// Checks to see if there are any sensors that are not overriden
+ /// calls the stop telescope function if it is not safe
+ /// Returns true if the telescope is safe to operate
+ /// Returns false if the telescope is not safe to operate
+ ///
+ public bool checkCurrentSensorAndOverrideStatus()
{
- int i = 0;
- foreach (RadioTelescopeControllerManagementThread rtmt in ThreadList)
+ // loop through all the current sensors
+ foreach (Sensor curSensor in Sensors)
{
- if (rtmt.RTController.RadioTelescope.Equals(RadioTelescope))
+ // if the sensor is in the ALARM state
+ if (curSensor.Status == SensorStatusEnum.ALARM)
{
- return i;
+ // check to see if there is an override for that sensor
+ if (ActiveOverrides.Find(i => i.Item == curSensor.Item) == null)
+ {
+ // if not, return false
+ // we should not be operating the telescope
+ logger.Fatal(Utilities.GetTimeStamp() + ": Telescope in DANGER due to fatal sensors");
+ safeTel = false;
+ RTController.ExecuteRadioTelescopeImmediateStop(MovementPriority.GeneralStop);
+ OverallSensorStatus = false;
+ return false;
+ }
}
-
- i++;
}
- return -1;
+ if(safeTel == false)
+ {
+ logger.Info(Utilities.GetTimeStamp() + ": Telescope in safe state.");
+ safeTel = true;
+ }
+ OverallSensorStatus = true;
+ return true;
}
+
}
}
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/PLCCommunication/ConversionHelper.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/PLCCommunication/ConversionHelper.cs
index 7f108a99..30988fdc 100644
--- a/ControlRoomApplication/ControlRoomApplication/Controllers/PLCCommunication/ConversionHelper.cs
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/PLCCommunication/ConversionHelper.cs
@@ -18,7 +18,22 @@ public static double RevolutionsToDegrees(double revolutions)
public static int DegreesToSteps(double degrees, int gearingRatio)
{
- return (int)(degrees * MotorConstants.STEPS_PER_REVOLUTION_BEFORE_GEARING * gearingRatio / 360);
+ return (int)(degrees * MotorConstants.STEPS_PER_REVOLUTION_BEFORE_GEARING * gearingRatio / 360.0);
+ }
+
+ // Only to be used with the slip ring, which has full 360-degree rotation
+ public static double StepsToDegrees_Normalized(int steps, int gearingRatio)
+ {
+ double baseOrientation = steps * 360.0 / (MotorConstants.STEPS_PER_REVOLUTION_BEFORE_GEARING * gearingRatio);
+
+ double normalizedOrientation = baseOrientation % 360;
+
+ if (normalizedOrientation < 0)
+ {
+ normalizedOrientation += 360;
+ }
+
+ return normalizedOrientation;
}
public static double StepsToDegrees(int steps, int gearingRatio)
@@ -26,6 +41,31 @@ public static double StepsToDegrees(int steps, int gearingRatio)
return steps * 360.0 / (MotorConstants.STEPS_PER_REVOLUTION_BEFORE_GEARING * gearingRatio);
}
+ public static int DegreesToSteps_Encoder( double degrees , int gearingRatio ) {
+ return (int)(degrees * MotorConstants.ENCODER_COUNTS_PER_REVOLUTION_BEFORE_GEARING * gearingRatio / 360.0);
+ }
+
+ // Only to be used with the slip ring, which has full 360-degree rotation
+ public static double StepsToDegrees_Encoder_Normalized(int steps, int gearingRatio)
+ {
+ double baseOrientation = steps * 360.0 / (MotorConstants.ENCODER_COUNTS_PER_REVOLUTION_BEFORE_GEARING * gearingRatio);
+
+ // Normalize the orientation between 0-360
+ double normalizedOrientation = baseOrientation % 360;
+
+ if (normalizedOrientation < 0)
+ {
+ normalizedOrientation += 360;
+ }
+
+ return normalizedOrientation;
+ }
+
+ public static double StepsToDegrees_Encoder( int steps , int gearingRatio )
+ {
+ return steps * 360.0 / (MotorConstants.ENCODER_COUNTS_PER_REVOLUTION_BEFORE_GEARING * gearingRatio);
+ }
+
public static double RPMToDPS(double rpms)
{
return rpms * 6;
@@ -33,12 +73,21 @@ public static double RPMToDPS(double rpms)
public static int DPSToSPS(double dpss, int gearingRatio)
{
- return (int)(dpss * MotorConstants.STEPS_PER_REVOLUTION_BEFORE_GEARING * gearingRatio / 360);
+ return DegreesToSteps( dpss , gearingRatio );
+ //return RPMToSPS( (dpss /6.0),gearingRatio);
+ }
+
+ public static double SPSToDPS( int sps, int gearingRatio ) {
+ return StepsToDegrees( sps , gearingRatio );
}
public static int RPMToSPS(double rpms, int gearingRatio)
{
- return DPSToSPS(RPMToDPS(rpms), gearingRatio);
+ return (int)((rpms * (double)(MotorConstants.STEPS_PER_REVOLUTION_BEFORE_GEARING * gearingRatio))/60.0);
+ }
+
+ public static double SPSToRPM( int sps , int gearingRatio ) {
+ return (sps*60)/ (double)(MotorConstants.STEPS_PER_REVOLUTION_BEFORE_GEARING * gearingRatio);
}
}
}
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/PLCCommunication/PLCClientCommunicationHandler.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/PLCCommunication/PLCClientCommunicationHandler.cs
deleted file mode 100644
index 72027fa7..00000000
--- a/ControlRoomApplication/ControlRoomApplication/Controllers/PLCCommunication/PLCClientCommunicationHandler.cs
+++ /dev/null
@@ -1,371 +0,0 @@
-using System;
-using System.Threading;
-using System.Net.Sockets;
-using ControlRoomApplication.Entities;
-
-namespace ControlRoomApplication.Controllers
-{
- public class PLCClientCommunicationHandler
- {
- private static readonly log4net.ILog logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
-
- private Thread StreamCommunicationThread;
- private Mutex StreamCommunicationThreadMutex;
- private bool KillStreamCommunicationThreadFlag;
- private bool HasActiveConnection { get; set; }
-
- private bool IncomingDataSet { get; set; }
- private byte[] IncomingData { get; set; }
-
- private bool OutgoingDataSet { get; set; }
- private byte[] OutgoingData { get; set; }
- private int ExpectedResponseDataSize { get; set; }
- private int ResponseTimeoutMS { get; set; }
-
- public PLCClientCommunicationHandler(string ip, int port)
- {
- StreamCommunicationThread = new Thread(() => RunTCPServer(ip, port));
- StreamCommunicationThreadMutex = new Mutex();
- KillStreamCommunicationThreadFlag = false;
- HasActiveConnection = false;
- }
-
- public void ConnectToServer()
- {
- StreamCommunicationThread.Start();
- }
-
- public void TerminateTCPServerConnection()
- {
- StreamCommunicationThreadMutex.WaitOne();
- KillStreamCommunicationThreadFlag = true;
- StreamCommunicationThreadMutex.ReleaseMutex();
- }
-
- private void RunTCPServer(string ip, int port)
- {
- if (HasActiveConnection)
- {
- logger.Info("[PLCClientCommunicationHandler] Failed to connect to TCP server client while attempting to bring up PLC Controller: instance is busy");
- return;
- }
-
- TcpClient PLCTCPClient;
- NetworkStream PLCTCPStream;
- try
- {
- PLCTCPClient = new TcpClient(ip, port);
- PLCTCPStream = PLCTCPClient.GetStream();
-
- }
- catch (Exception e)
- {
- if ((e is ArgumentNullException)
- || (e is ArgumentOutOfRangeException)
- || (e is SocketException)
- || (e is InvalidOperationException)
- || (e is ObjectDisposedException))
- {
- logger.Info("[PLCClientCommunicationHandler] Failed to connect to TCP server client while attempting to bring up PLC Controller: error establishing connection");
- HasActiveConnection = false;
- return;
- }
- else
- {
- // Unexpected exception type
- throw e;
- }
- }
-
- HasActiveConnection = true;
-
- byte[] TemporaryResponseBuffer;
-
- bool KeepAlive = !KillStreamCommunicationThreadFlag;
- while (KeepAlive)
- {
- StreamCommunicationThreadMutex.WaitOne();
-
- if (PLCTCPStream.DataAvailable)
- {
- TemporaryResponseBuffer = new byte[ExpectedResponseDataSize];
-
- int TotalRead = 0;
- while (PLCTCPStream.DataAvailable)
- {
- TotalRead += PLCTCPStream.Read(TemporaryResponseBuffer, TotalRead, TemporaryResponseBuffer.Length);
- }
-
- if (TotalRead != ExpectedResponseDataSize)
- {
- logger.Info("[PLCClientCommunicationHandler] ERROR, inconsistent packet size: " + TotalRead.ToString() + " vs. " + ExpectedResponseDataSize.ToString());
- }
-
- IncomingData = TemporaryResponseBuffer;
- IncomingDataSet = true;
- }
-
- if (OutgoingDataSet)
- {
- if (OutgoingData.Length <= 0)
- {
- logger.Info("[PLCClientCommunicationHandler] No data found to be sent.");
- OutgoingDataSet = false;
- }
-
- PLCTCPStream.Write(OutgoingData, 0, OutgoingData.Length);
-
- OutgoingDataSet = false;
- }
-
- KeepAlive = !KillStreamCommunicationThreadFlag && PLCTCPClient.Connected;
-
- StreamCommunicationThreadMutex.ReleaseMutex();
- }
-
- logger.Info("[PLCClientCommunicationHandler] Exited main loop.");
- }
-
- private byte[] ReadResponse()
- {
- if (ExpectedResponseDataSize == 0)
- {
- logger.Info("[PLCClientCommunicationHandler] WARNING: Expected message size was 0.");
- return null;
- }
-
- DateTime StartTime = DateTime.UtcNow;
- while (true)
- {
- int AllowableTimeout = ResponseTimeoutMS - (int)((DateTime.UtcNow - StartTime).TotalMilliseconds);
- if (AllowableTimeout <= 0)
- {
- logger.Info("[PLCClientCommunicationHandler] Timed out waiting for response.");
- return null;
- }
-
- if (StreamCommunicationThreadMutex.WaitOne(AllowableTimeout))
- {
- if (IncomingDataSet)
- {
- byte[] DataCopy = new byte[IncomingData.Length];
- Array.Copy(IncomingData, DataCopy, DataCopy.Length);
-
- IncomingDataSet = false;
-
- StreamCommunicationThreadMutex.ReleaseMutex();
-
- return DataCopy;
- }
- else
- {
- StreamCommunicationThreadMutex.ReleaseMutex();
- }
- }
- }
- }
-
- // As far as I'm aware, this is not being used at the moment anymore. However, Garret had mentioned
- // the desire for async functionality, so I won't get rid of this just yet. (And I'll leave
- // SendMessageWithResponse how it for now as a result.)
- private void SendMessage(byte[] ByteData, int ExpectedResponseSize = 0, int TimeoutMS = 0)
- {
- StreamCommunicationThreadMutex.WaitOne();
-
- ExpectedResponseDataSize = ExpectedResponseSize;
- ResponseTimeoutMS = TimeoutMS;
- OutgoingData = ByteData;
- OutgoingDataSet = true;
-
- StreamCommunicationThreadMutex.ReleaseMutex();
-
- }
-
- private byte[] SendMessageWithResponse(byte[] ByteData, int ExpectedResponseSize, int TimeoutMS = 10000)
- {
- SendMessage(ByteData, ExpectedResponseSize, TimeoutMS);
- return ReadResponse();
- }
-
- public byte[] RequestMessageSend(PLCCommandAndQueryTypeEnum MessageType, params object[] MessageParameters)
- {
- byte[] NetOutgoingMessage =
- {
- 0x13, 0x0,
- PLCCommandAndQueryTypeConversionHelper.ConvertToByte(MessageType),
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
- };
-
- PLCCommandResponseExpectationEnum ResponseExpectationValue;
-
- switch (MessageType)
- {
- case PLCCommandAndQueryTypeEnum.TEST_CONNECTION:
- case PLCCommandAndQueryTypeEnum.GET_CURRENT_AZEL_POSITIONS:
- case PLCCommandAndQueryTypeEnum.GET_CURRENT_LIMIT_SWITCH_STATUSES:
- case PLCCommandAndQueryTypeEnum.GET_CURRENT_SAFETY_INTERLOCK_STATUS:
- {
- ResponseExpectationValue = PLCCommandResponseExpectationEnum.FULL_RESPONSE;
- break;
- }
-
- case PLCCommandAndQueryTypeEnum.CANCEL_ACTIVE_OBJECTIVE_AZEL_POSITION:
- case PLCCommandAndQueryTypeEnum.SHUTDOWN:
- case PLCCommandAndQueryTypeEnum.CALIBRATE:
- case PLCCommandAndQueryTypeEnum.CONTROLLED_STOP:
- case PLCCommandAndQueryTypeEnum.IMMEDIATE_STOP:
- {
- ResponseExpectationValue = PLCCommandResponseExpectationEnum.MINOR_RESPONSE;
- break;
- }
-
- case PLCCommandAndQueryTypeEnum.SET_CONFIGURATION:
- {
- ResponseExpectationValue = PLCCommandResponseExpectationEnum.MINOR_RESPONSE;
-
- int StartSpeedAzimuth = (int)MessageParameters[0];
- int StartSpeedElevation = (int)MessageParameters[1];
- int HomeTimeoutAzimuth = (int)MessageParameters[2];
- int HomeTimeoutElevation = (int)MessageParameters[3];
-
- NetOutgoingMessage[3] = 0x84;
- NetOutgoingMessage[4] = 0x00;
- NetOutgoingMessage[5] = 0x00;
- NetOutgoingMessage[6] = 0x00;
-
- NetOutgoingMessage[7] = 0x0;
- NetOutgoingMessage[8] = (byte)(StartSpeedAzimuth / 0xFFFF);
- NetOutgoingMessage[9] = (byte)((StartSpeedAzimuth >> 8) & 0xFF);
- NetOutgoingMessage[10] = (byte)(StartSpeedAzimuth & 0xFF);
-
- NetOutgoingMessage[11] = 0x0;
- NetOutgoingMessage[12] = (byte)(StartSpeedElevation / 0xFFFF);
- NetOutgoingMessage[13] = (byte)((StartSpeedElevation >> 8) & 0xFF);
- NetOutgoingMessage[14] = (byte)(StartSpeedElevation & 0xFF);
-
- NetOutgoingMessage[15] = (byte)(HomeTimeoutAzimuth >> 8);
- NetOutgoingMessage[16] = (byte)(HomeTimeoutAzimuth & 0xFF);
-
- NetOutgoingMessage[17] = (byte)(HomeTimeoutElevation >> 8);
- NetOutgoingMessage[18] = (byte)(HomeTimeoutElevation & 0xFF);
-
- break;
- }
-
- case PLCCommandAndQueryTypeEnum.SET_OBJECTIVE_AZEL_POSITION:
- {
- ResponseExpectationValue = PLCCommandResponseExpectationEnum.MINOR_RESPONSE;
-
- Orientation ObjectiveOrientation = (Orientation)MessageParameters[0];
- Array.Copy(BitConverter.GetBytes(ObjectiveOrientation.Azimuth), 0, NetOutgoingMessage, 3, 8);
- Array.Copy(BitConverter.GetBytes(ObjectiveOrientation.Elevation), 0, NetOutgoingMessage, 11, 8);
-
- break;
- }
-
- case PLCCommandAndQueryTypeEnum.START_JOG_MOVEMENT:
- {
- ResponseExpectationValue = PLCCommandResponseExpectationEnum.MINOR_RESPONSE;
-
- RadioTelescopeAxisEnum AxisEnum = (RadioTelescopeAxisEnum)MessageParameters[0];
- int AxisJogSpeed = (int)MessageParameters[1];
- bool JogClockwise = (bool)MessageParameters[2];
-
- switch (AxisEnum)
- {
- case RadioTelescopeAxisEnum.AZIMUTH:
- {
- NetOutgoingMessage[3] = 0x1;
- break;
- }
-
- case RadioTelescopeAxisEnum.ELEVATION:
- {
- NetOutgoingMessage[3] = 0x2;
- break;
- }
-
- default:
- {
- throw new ArgumentException("Invalid RadioTelescopeAxisEnum value seen while preparing jog movement bytes: " + AxisEnum.ToString());
- }
- }
-
- NetOutgoingMessage[4] = 0x0;
- NetOutgoingMessage[5] = (byte)(AxisJogSpeed / 0xFFFF);
- NetOutgoingMessage[6] = (byte)((AxisJogSpeed >> 8) & 0xFF);
- NetOutgoingMessage[7] = (byte)(AxisJogSpeed & 0xFF);
-
- NetOutgoingMessage[8] = (byte)(JogClockwise ? 0x1 : 0x2);
-
- break;
- }
-
- case PLCCommandAndQueryTypeEnum.TRANSLATE_AZEL_POSITION:
- {
- ResponseExpectationValue = PLCCommandResponseExpectationEnum.MINOR_RESPONSE;
-
- RadioTelescopeAxisEnum AxisEnum = (RadioTelescopeAxisEnum)MessageParameters[0];
- int AxisJogSpeed = (int)MessageParameters[1];
- int position = (int)MessageParameters[2];
-
- switch (AxisEnum)
- {
- case RadioTelescopeAxisEnum.AZIMUTH:
- {
- NetOutgoingMessage[3] = 0x1;
- break;
- }
-
- case RadioTelescopeAxisEnum.ELEVATION:
- {
- NetOutgoingMessage[3] = 0x2;
- break;
- }
-
- default:
- {
- throw new ArgumentException("Invalid RadioTelescopeAxisEnum value seen while preparing relative movement bytes: " + AxisEnum.ToString());
- }
- }
-
- NetOutgoingMessage[4] = 0x0;
- NetOutgoingMessage[5] = (byte)(AxisJogSpeed / 0xFFFF);
- NetOutgoingMessage[6] = (byte)((AxisJogSpeed >> 8) & 0xFF);
- NetOutgoingMessage[7] = (byte)(AxisJogSpeed & 0xFF);
-
- if (position > 0)
- {
- NetOutgoingMessage[8] = 0x0;
- NetOutgoingMessage[9] = (byte)(position / 0xFFFF);
- NetOutgoingMessage[10] = (byte)((position >> 8) & 0xFF);
- NetOutgoingMessage[11] = (byte)(position & 0xFF);
- }
- else
- {
- NetOutgoingMessage[8] = 0xFF;
- NetOutgoingMessage[9] = (byte)((position / 0xFFFF) - 1);
- NetOutgoingMessage[10] = (byte)((position >> 8) & 0xFF);
- NetOutgoingMessage[11] = (byte)(position & 0xFF);
- }
-
- break;
- }
-
- default:
- {
- throw new ArgumentException("Illegal PLCCommandAndQueryTypeEnum value: " + MessageType.ToString());
- }
- }
-
- NetOutgoingMessage[2] += (byte)(PLCCommandResponseExpectationConversionHelper.ConvertToByte(ResponseExpectationValue) * 0x40);
-
- // This is the expected response size of anything from the PLC (simulated or real), minor or full response.
- // See the TCP/IP packet contents google sheets file describing this under Wiki Documentation -> Control Room in the shared GDrive
- byte ExpectedResponseSize = (ResponseExpectationValue == PLCCommandResponseExpectationEnum.FULL_RESPONSE) ? (byte)0x13 : (byte)0x3;
-
- return SendMessageWithResponse(NetOutgoingMessage, ExpectedResponseSize);
- }
- }
-}
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/PLCCommunication/PLCDrivers/AbstractPLCDriver.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/PLCCommunication/PLCDrivers/AbstractPLCDriver.cs
index e942f3e6..6227afe2 100644
--- a/ControlRoomApplication/ControlRoomApplication/Controllers/PLCCommunication/PLCDrivers/AbstractPLCDriver.cs
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/PLCCommunication/PLCDrivers/AbstractPLCDriver.cs
@@ -5,6 +5,15 @@
using System.Net;
using System.Net.Sockets;
using System.Threading;
+using System.Threading.Tasks;
+using ControlRoomApplication.Simulators.Hardware;
+using ControlRoomApplication.Constants;
+using ControlRoomApplication.Controllers.Sensors;
+using ControlRoomApplication.Controllers.PLCCommunication;
+using System.Collections.Generic;
+using static ControlRoomApplication.Constants.MCUConstants;
+using ControlRoomApplication.Controllers.PLCCommunication.PLCDrivers.MCUManager;
+using ControlRoomApplication.Controllers.PLCCommunication.PLCDrivers.MCUManager.Enumerations;
namespace ControlRoomApplication.Controllers
{
@@ -15,23 +24,27 @@ public abstract class AbstractPLCDriver : HeartbeatInterface {
protected Thread ClientManagmentThread;
+ public LimitSwitchData limitSwitchData;
+ public HomeSensorData homeSensorData;
+ public MiscPlcInput plcInput;
+ protected PLCEvents pLCEvents;
+ public OverrideSwitchData Overrides { get; set; }
///
- ///
+ /// This is the priority of the currently-running move. This will be "None" if no move is currently running, otherwise it will
+ /// reflect the priority.
///
- ///
- ///
- ///
- ///
- public AbstractPLCDriver(IPAddress local_ip_address, IPAddress MCU_ip_address, int MCU_port, int PLC_port) { }
+ public abstract MovementPriority CurrentMovementPriority { get; set; }
+
///
- ///
+ /// the PLC will look for the server that we create in the control room, the control room will look for the remote server that the MCU has setup
///
- ///
- ///
- ///
- ///
- public AbstractPLCDriver(string local_ip, string MCU_ip, int MCU_port, int PLC_port) : this(IPAddress.Parse(local_ip), IPAddress.Parse(MCU_ip), MCU_port, PLC_port) { }
+ /// IP adress to start the local modbus server on
+ /// IP adress of the MCU
+ /// port the MCU is using
+ /// port to start the local modbus server on
+ /// if true will automaticly start the modbus server
+ public AbstractPLCDriver(string local_ip, string MCU_ip, int MCU_port, int PLC_port) { }
protected override bool KillHeartbeatComponent() {
@@ -39,13 +52,14 @@ protected override bool KillHeartbeatComponent() {
return true;
}
- // public delegate void ReadReghandler(object sender, ModbusSlaveRequestEventArgs e);
-
+ public bool publicKillHeartbeatComponent() {
+ return KillHeartbeatComponent();
+ }
///
/// modbuss server implamentation specific to each device
///
- protected abstract void HandleClientManagementThread();
+ public abstract void HandleClientManagementThread();
///
@@ -59,49 +73,90 @@ protected override bool KillHeartbeatComponent() {
///
public abstract bool RequestStopAsyncAcceptingClientsAndJoin();
+
public abstract void Bring_down();
- public abstract bool Test_Conection();
+ public abstract bool Test_Connection();
- public abstract Orientation read_Position();
+ public abstract Orientation GetMotorEncoderPosition();
- public abstract bool Cancle_move();
+ public abstract MovementResult Cancel_move();
- public abstract bool Shutdown_PLC_MCU();
+ // All of the "scripts" are here all the way to....
+ // Control Scripts
- public abstract bool Calibrate();
+ ///
+ /// Moves both axes to where the homing sensors are. After this is run, the position offset needs applied to the motors, and then
+ /// the absolute encoders.
+ ///
+ /// True if homing was successful, false if it failed
+ public abstract MovementResult HomeTelescope();
- public abstract bool Configure_MCU(int startSpeedAzimuth, int startSpeedElevation, int homeTimeoutAzimuth, int homeTimeoutElevation);
+ public abstract bool Configure_MCU(double startSpeedAzimuth, double startSpeedElevation, int homeTimeoutAzimuth, int homeTimeoutElevation);
- public abstract bool Controled_stop(RadioTelescopeAxisEnum axis, bool both);
+ public abstract MovementResult ControlledStop();
- public abstract bool Immediade_stop();
+ public abstract MovementResult ImmediateStop();
- public abstract bool relative_move(int programmedPeakSpeedAZInt, ushort ACCELERATION, int positionTranslationAZ, int positionTranslationEL);
+ public abstract MovementResult RelativeMove(int programmedPeakSpeedAZInt, int programmedPeakSpeedELInt, int positionTranslationAZ, int positionTranslationEL, Orientation targetOrientation);
- public abstract bool Move_to_orientation(Orientation target_orientation, Orientation current_orientation);
+ public abstract MovementResult MoveToOrientation(Orientation target_orientation, Orientation current_orientation);
- public abstract bool Start_jog(RadioTelescopeAxisEnum axis, int speed, bool clockwise);
+ public abstract MovementResult StartBothAxesJog(double azSpeed, RadioTelescopeDirectionEnum azDirection, double elSpeed, RadioTelescopeDirectionEnum elDirection);
public abstract bool Get_interlock_status();
- public abstract bool[] Get_Limit_switches();
+ public abstract void setregvalue(ushort adr, ushort value);
- public abstract bool[] GET_MCU_Status();
+ public abstract ushort getregvalue(ushort adr);
+ ///
+ /// get an array of boolens representiing the register described on pages 76 -79 of the mcu documentation
+ /// does not suport RadioTelescopeAxisEnum.BOTH
+ /// see for description of each bit
+ ///
+ ///
+ ///
+ public abstract bool[] GET_MCU_Status( RadioTelescopeAxisEnum axis );
+ public abstract void setTelescopeType(RadioTelescopeTypeEnum type);
///
- /// processes requests from the clientmanagementthread
- /// !not used in the production PLC driver
- ///is used in simulation although it may not be later
+ /// Resets any errors the MCU encounters. This could be for either of the motors.
///
- ///
- ///
- ///
- //protected abstract bool ProcessRequest(NetworkStream ActiveClientStream, byte[] query);
+ public abstract void ResetMCUErrors();
+ ///
+ /// This will check for any errors present in the MCU's registers.
+ ///
+ /// A list of errors present in the MCU's registers
+ public abstract List> CheckMCUErrors();
+ ///
+ /// This will interrupt the current movement, wait until it has stopped, and then
+ /// end when the movement has stopped.
+ ///
+ /// If no motors are moving when this is called, then it will not wait, and just be
+ /// able to pass through.
+ ///
+ /// Specify whether or not this is a critical movement interrupt and perform and immediate stop
+ /// Specify whether or not this is a software-stop interrupt
+ public abstract bool InterruptMovementAndWaitUntilStopped(bool isCriticalMovementInterrupt = false, bool isSoftwareStopInterrupt = false);
+ ///
+ /// Checks to see if the motors are currently moving.
+ ///
+ /// Azimuth, elevation, or both.
+ /// True if moving, false if not moving.
+ public abstract bool MotorsCurrentlyMoving(RadioTelescopeAxisEnum axis = RadioTelescopeAxisEnum.BOTH);
+
+ public abstract void SetFinalOffset(Orientation finalPos);
+
+ ///
+ /// Gets the direction that the specfied axis is moving.
+ ///
+ /// Azimuth or elevation.
+ /// The direction that the specfied axis is spinning.
+ public abstract RadioTelescopeDirectionEnum GetRadioTelescopeDirectionEnum(RadioTelescopeAxisEnum axis);
}
}
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/PLCCommunication/PLCDrivers/MCUManager/Enumerations/MCUCommandType.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/PLCCommunication/PLCDrivers/MCUManager/Enumerations/MCUCommandType.cs
new file mode 100644
index 00000000..ccc378a1
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/PLCCommunication/PLCDrivers/MCUManager/Enumerations/MCUCommandType.cs
@@ -0,0 +1,114 @@
+using ControlRoomApplication.Entities;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ControlRoomApplication.Controllers.PLCCommunication.PLCDrivers.MCUManager
+{
+ ///
+ /// These are all for the First Word Azimuth (registerData[0]) OR First word Elevation
+ ///
+ public enum MCUCommandType : ushort
+ {
+ ///
+ /// First register bit (registerData[0])
+ ///
+ RelativeMove = 0x0002,
+
+ ///
+ /// First register bit (registerData[0])
+ ///
+ CancelMove = 0x0003,
+
+ ///
+ /// First register bit (registerData[0])
+ ///
+ ControlledStop = 0x0004,
+
+ ///
+ /// first register bit (registerData[0])
+ ///
+ ImmediateStop = 0x0010,
+
+ ///
+ /// first register bit (registerData[0])
+ ///
+ Home = 0x0040,
+
+ ///
+ /// first register bit (registerData[0])
+ ///
+ ClearErrors = 0x0800,
+
+ ///
+ /// first register bit (registerData[0])
+ ///
+ Configure = 0x852c,
+
+ ///
+ /// A jog movement. If a movement is a jog, the first word must be the direction the telescope
+ /// is moving.
+ ///
+ Jog,
+
+ ///
+ /// A movement used to stop the telescope. This is to be used only with the "Hold Move" complete message,
+ /// found in
+ ///
+ HoldMove,
+
+ ///
+ /// This is empty data. If we want a register to be empty, this is used.
+ ///
+ EmptyData = 0x0000
+ }
+
+ ///
+ /// This enum lines up for the vast majority of the register data we send over, but there are some exceptions. For example, stop moves only use a couple of the registers
+ /// to send their information over, so the this entire list does not line up for them (the first or second word does this). The homing command or the reset errors command also do
+ /// not line up with this list. The majority of moves (we really only use relative and jog moves) do line up with this list.
+ /// THESE ARE REALLY ONLY FOR RELATIVE MOVES
+ ///
+ enum MCURegPos : int
+ {
+ ///
+ /// AZIMUTH REGISTERS
+ ///
+ firstWordAzimuth,
+ secondWordAzimuth,
+ firstPosAzimuth,
+ secondPosAzimuth,
+ firstSpeedAzimuth,
+ secondSpeedAzimuth,
+ firstAccelerationAzimuth,
+ secondAccelerationAzimuth,
+
+ ///
+ /// NOTE: these registers are never used from the control room, so they very well might not line up with the names I've used below. From the data sheet,
+ /// based on the pattern of the previous registers my best guess is that these correspond to spots registerData[8] & registerData[9]
+ /// ( I think this is better than leaving them blank spots in the enum )
+ ///
+ firstDecelerationAzimuth,
+ secondDecelerationAzimuth,
+
+ ///
+ /// ELEVATION REGISTERS
+ ///
+ firstWordElevation,
+ secondWordElevation,
+ firstPosElevation,
+ secondPosElevation,
+ firstSpeedElevation,
+ secondSpeedElevation,
+ firstAccelerationElevation,
+ secondAccelerationElevation,
+
+ ///
+ /// same note as above, these are never used by the control room, but for completeness sake I have them listed here
+ ///
+ firstDecelerationElevation,
+ secondDecelerationElevation,
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/PLCCommunication/PLCDrivers/MCUManager/Enumerations/MCUNetworkStatus.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/PLCCommunication/PLCDrivers/MCUManager/Enumerations/MCUNetworkStatus.cs
new file mode 100644
index 00000000..d2369e25
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/PLCCommunication/PLCDrivers/MCUManager/Enumerations/MCUNetworkStatus.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ControlRoomApplication.Controllers.PLCCommunication.PLCDrivers.MCUManager.Enumerations
+{
+ ///
+ /// This contains the possible network statuses the MCU may have.
+ ///
+ public enum MCUNetworkStatus : ushort
+ {
+ ///
+ /// If this is set to 1, it means the modbus server has encountered an error, and needs reset.
+ ///
+ MCUNetworkDisconnected = 13,
+
+ ///
+ /// This is the heart beat bit that alternates between 0 and 1 every 250ms
+ ///
+ MCUHeartBeat = 14
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/PLCCommunication/PLCDrivers/MCUManager/Enumerations/MCUResetResult.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/PLCCommunication/PLCDrivers/MCUManager/Enumerations/MCUResetResult.cs
new file mode 100644
index 00000000..036567fe
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/PLCCommunication/PLCDrivers/MCUManager/Enumerations/MCUResetResult.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ControlRoomApplication.Controllers.PLCCommunication.PLCDrivers.MCUManager.Enumerations
+{
+ public enum MCUResetResult
+ {
+ Success,
+ Failed
+ }
+}
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/PLCCommunication/PLCDrivers/MCUManager/Enumerations/MovePriority.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/PLCCommunication/PLCDrivers/MCUManager/Enumerations/MovePriority.cs
new file mode 100644
index 00000000..59992dcf
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/PLCCommunication/PLCDrivers/MCUManager/Enumerations/MovePriority.cs
@@ -0,0 +1,49 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ControlRoomApplication.Controllers.PLCCommunication.PLCDrivers.MCUManager
+{
+ ///
+ /// This will allow us to prioritize movement commands to the MCU. A higher priority movement coming in
+ /// will stop the currently-running movement and start the new one. The lower the number, the higher the priority
+ /// (with the exception of "None").
+ ///
+ public enum MovementPriority
+ {
+ ///
+ /// This priority is present if one has not yet been initialized, or if no movement is currently running.
+ ///
+ None,
+
+ ///
+ /// This is the lowest priority movement, which is reserved only for use with appointments, which are cued
+ /// up in RadioTelescopeControllerManagementThread .
+ ///
+ Appointment,
+
+ ///
+ /// This denotes manual movements that the user would send through scripts or manual az/el movements on the
+ /// RT Control Form.
+ ///
+ Manual,
+
+ ///
+ /// This denotes a jog movement, which is technically the same priority as Manual, but used so the GeneralStop
+ /// can differentiate the two movements.
+ ///
+ Jog,
+
+ ///
+ /// This is a movement command for the general stopping of any lower-priority movement commands.
+ ///
+ GeneralStop,
+
+ ///
+ /// These are movements that must override all other movements, such as stop commands or limit switch recovery.
+ ///
+ Critical
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/PLCCommunication/PLCDrivers/MCUManager/Enumerations/MovementResult.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/PLCCommunication/PLCDrivers/MCUManager/Enumerations/MovementResult.cs
new file mode 100644
index 00000000..950ebe69
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/PLCCommunication/PLCDrivers/MCUManager/Enumerations/MovementResult.cs
@@ -0,0 +1,108 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ControlRoomApplication.Controllers.PLCCommunication.PLCDrivers.MCUManager.Enumerations
+{
+ ///
+ /// This is returned after a movement is completed, denoting whether it was successful or a failure.
+ ///
+ public enum MovementResult
+ {
+ ///
+ /// Result has not yet been assigned.
+ ///
+ None,
+
+ ///
+ /// The movement was successful and the position is correct.
+ ///
+ Success,
+
+ ///
+ /// A limit switch was hit during the movement, so it was cancelled.
+ ///
+ LimitSwitchHit,
+
+ ///
+ /// An emergency stop was hit during the movement, so it was cancelled.
+ ///
+ EstopHit,
+
+ ///
+ /// A limit switch or emergency stop was hit during the movement, so it was cancelled.
+ ///
+ ///
+ /// This exists because the MCU error bit denoting limit switch or estop activity are shared.
+ ///
+ LimitSwitchOrEstopHit,
+
+ ///
+ /// The telescope elevation was out of range and was moving furthur out of range, so it was cancelled.
+ ///
+ SoftwareStopHit,
+
+ ///
+ /// The movement took too long to complete, so it timed out.
+ ///
+ TimedOut,
+
+ ///
+ /// The movement completed, but the position is not correct.
+ ///
+ IncorrectPosition,
+
+ ///
+ /// The movement was interrupted by either a higher-priority movement, or sensor data requested a stop.
+ ///
+ Interrupted,
+
+ ///
+ /// The movement was ended early because one or more MCU error bits were set.
+ ///
+ McuErrorBitSet,
+
+ ///
+ /// The movement will not be sent to the MCU because a part of the command was invalid.
+ ///
+ ValidationError,
+
+ ///
+ /// If you try to run a movement while one with equal or higher priority is running, this will be returned.
+ ///
+ AlreadyMoving,
+
+ ///
+ /// If the sensors are communicating unsafe data, blocks the incoming move.
+ ///
+ SensorsNotSafe,
+
+ ///
+ /// This is only used for Jog commands if they are running overtop of a movement that is lower priority.
+ ///
+ StoppingCurrentMove,
+
+ ///
+ /// Used if the RemoteListener class failed to parse a TCP command and movement wasn't started
+ ///
+ InvalidCommand,
+
+ /// This is only used for the "moveradiotelescopebyxdegrees" function in RadioTelescopeController
+ /// will be returned if a relative move would put the telescope past software limits
+ ///
+ InvalidRequestedPostion,
+
+ ///
+ /// This is only used for the "moveradiotelescopebyxdegrees" function in RadioTelescopeController
+ /// will be returned if a requested azimuth move is too large
+ ///
+ RequestedAzimuthMoveTooLarge,
+
+ /// This is set if the command could not be sent to the MCU for whatever reason. The most common reason this
+ /// may happen is if the MCU goes offline, Ethernet becomes disconnected, etc.
+ ///
+ CouldNotSendCommand
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/PLCCommunication/PLCDrivers/MCUManager/MCUCommand.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/PLCCommunication/PLCDrivers/MCUManager/MCUCommand.cs
new file mode 100644
index 00000000..ae3e4aa4
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/PLCCommunication/PLCDrivers/MCUManager/MCUCommand.cs
@@ -0,0 +1,93 @@
+using ControlRoomApplication.Entities;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace ControlRoomApplication.Controllers.PLCCommunication.PLCDrivers.MCUManager
+{
+ ///
+ /// used to keep track of what comand the MCU is running
+ ///
+ public class MCUCommand : IDisposable
+ {
+ ///
+ /// Stores the data that is to be sent to the MCU.
+ ///
+ public ushort[] commandData;
+
+ ///
+ /// High-level information about the command's general purpose.
+ ///
+ public MCUCommandType CommandType;
+
+ ///
+ /// True when a command has completed. Used to determine when the next move can be sent.
+ ///
+ public bool completed = false;
+
+ ///
+ /// this will be set when returnd to the calling function if the move could not be run for some reason
+ ///
+ public Exception CommandError;
+
+ ///
+ /// these variables set so that different parts of the MCUManager can calculate how parts of the operation will take
+ ///
+ public int AzimuthSpeed, ElevationSpeed, AZ_ACC = 50, EL_ACC = 50;
+
+ ///
+ /// Determines the direction of motion of the azimuth motor.
+ ///
+ public RadioTelescopeDirectionEnum AzimuthDirection;
+
+ ///
+ /// Determines the direction of motion fo the elevation motor.
+ ///
+ public RadioTelescopeDirectionEnum ElevationDirection;
+
+ ///
+ /// create a MCU command and record the current time
+ ///
+ ///
+ ///
+ public MCUCommand(ushort[] data, MCUCommandType CMDType)
+ {
+ CommandType = CMDType;
+ commandData = data;
+ }
+
+ ///
+ /// Create a command for movement. Only the "data" field is sent to the MCU; the rest of the fields
+ /// exist for internal tracking and estimations within the MCU manager.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public MCUCommand(ushort[] data, MCUCommandType CMDType, RadioTelescopeDirectionEnum azDir, RadioTelescopeDirectionEnum elDir, int AZSpeed, int ElSpeed)
+ {
+ CommandType = CMDType;
+ commandData = data;
+ AzimuthDirection = azDir;
+ ElevationDirection = elDir;
+ AzimuthSpeed = AZSpeed;
+ ElevationSpeed = ElSpeed;
+ }
+
+ public CancellationTokenSource timeout;
+
+ public void Dispose()
+ {
+ try
+ {
+ timeout.Dispose();
+ }
+ catch { }
+ }
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/PLCCommunication/PLCDrivers/MCUManager/MCUManager.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/PLCCommunication/PLCDrivers/MCUManager/MCUManager.cs
new file mode 100644
index 00000000..13c9fa45
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/PLCCommunication/PLCDrivers/MCUManager/MCUManager.cs
@@ -0,0 +1,1174 @@
+using ControlRoomApplication.Constants;
+using ControlRoomApplication.Controllers.PLCCommunication;
+using ControlRoomApplication.Controllers.PLCCommunication.PLCDrivers.MCUManager;
+using ControlRoomApplication.Controllers.PLCCommunication.PLCDrivers.MCUManager.Enumerations;
+using ControlRoomApplication.Entities;
+using ControlRoomApplication.Entities.Configuration;
+using ControlRoomApplication.Simulators.Hardware;
+using ControlRoomApplication.Util;
+using Modbus.Device;
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.Sockets;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using static ControlRoomApplication.Constants.MCUConstants;
+
+namespace ControlRoomApplication.Controllers {
+ public class MCUManager {
+ private static readonly log4net.ILog logger = log4net.LogManager.GetLogger( System.Reflection.MethodBase.GetCurrentMethod().DeclaringType );
+ public bool MovementInterruptFlag = false;
+ public bool CriticalMovementInterruptFlag = false;
+ public bool SoftwareStopInterruptFlag = false;
+
+ private long MCU_last_contact = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
+ private Thread HeartbeatMonitorThread;
+ private bool HeartbeatMonitorRunning;
+ private int AZStartSpeed = 0;
+ private int ELStartSpeed = 0;
+ public ModbusIpMaster MCUModbusMaster;
+ private TcpClient MCUTCPClient;
+ private MCUConfigurationAxys Current_AZConfiguration;
+ private MCUConfigurationAxys Current_ELConfiguration;
+ ///
+ /// this value should not be changed from outside the MCU class
+ ///
+ private MCUCommand RunningCommand= new MCUCommand(new ushort[20], MCUCommandType.EmptyData) { completed = true };
+ private MCUCommand PreviousCommand = new MCUCommand(new ushort[20], MCUCommandType.EmptyData) { completed = true };
+ public Orientation FinalPositionOffset { get; set; }
+
+ private int McuPort;
+ private string McuIp;
+ private RadioTelescopeTypeEnum telescopeType;
+
+ public MCUManager(string ip, int port) {
+ McuPort = port;
+ McuIp = ip;
+
+ logger.Info(Utilities.GetTimeStamp() + ": Attempting to connect to the MCU...");
+ ConnectToModbusServer();
+
+ HeartbeatMonitorThread = new Thread(new ThreadStart(HeartbeatMonitor)) { Name = "MCU Heartbeat Monitor Thread" };
+ FinalPositionOffset = new Orientation(0, 0);
+ }
+
+ ///
+ /// Attempts to connect to the MCU either for the first time, or after the connection has been lost.
+ ///
+ /// Result of whether or not the connection was successful.
+ private bool ConnectToModbusServer() {
+
+ // Attempt to connect to the MCU's TCP server
+ try
+ {
+ MCUTCPClient = new TcpClient(McuIp, McuPort);
+ }
+ catch
+ {
+ return false;
+ }
+
+ try
+ {
+ MCUModbusMaster = ModbusIpMaster.CreateIp(MCUTCPClient);
+ }
+ catch
+ {
+ return false;
+ }
+
+ logger.Info(Utilities.GetTimeStamp() + ": Successfully connected to the MCU and the Modbus Master!");
+
+ return true;
+ }
+
+ ///
+ /// Reads registers from the MCU without writing. This is public so the PLC can also read registers if needed.
+ ///
+ /// The starting address that we are reading.
+ /// The number of addresses to read.
+ /// Registers that were requested.
+ public ushort[] ReadMCURegisters(ushort address, ushort length)
+ {
+ ushort[] value = new ushort[length];
+ try
+ {
+ value = MCUModbusMaster.ReadHoldingRegistersAsync(address, length).GetAwaiter().GetResult();
+ }
+
+ // This may happen if we lose connection to the MCU
+ catch (InvalidOperationException)
+ {
+ value = new ushort[50];
+ }
+
+ return value;
+ }
+
+ ///
+ /// Writes data to the MCU registers based on what motor axis we want to send information to.
+ ///
+ ///
+ /// If elevation or azimuth the selected axis type, the ushort size should only be 10.
+ /// If "both" are selected, then the ushort size should be 20. This is the default selection.
+ /// If elevation is selected, then an additional offset is required to skip the azimuth registers, which
+ /// is automatically handled in this function.
+ ///
+ /// The command data we want to send.
+ /// The motor axis registers we want to modify.
+ /// Whether or not the writing was successful.
+ private bool WriteMCURegisters(ushort[] data, RadioTelescopeAxisEnum axis = RadioTelescopeAxisEnum.BOTH)
+ {
+ // Offset used to skip azimuth registers if we're only writing to elevation
+ ushort offset = 0;
+ if (axis == RadioTelescopeAxisEnum.ELEVATION) offset = 10;
+
+ try
+ {
+ MCUModbusMaster.WriteMultipleRegistersAsync((ushort)(MCUConstants.ACTUAL_MCU_WRITE_REGISTER_START_ADDRESS + offset), data).GetAwaiter().GetResult();
+ }
+ catch (InvalidOperationException) {
+
+ logger.Error(Utilities.GetTimeStamp() + ": The MCU failed to receive the command, and is either offline or the connection has been terminated.");
+ return false;
+ }
+
+ return true;
+ }
+
+ ///
+ /// This thread will read the heartbeat bit in the MCU status to determine if the MCU is still alive.
+ /// This loops around every 250 ms.
+ ///
+ private void HeartbeatMonitor() {
+
+ int lastHeartBeat = 0;
+ DateTime lastConnectAttempt = DateTime.Now;
+ bool inError = false;
+
+ while(HeartbeatMonitorRunning) {
+
+ ushort[] networkStatus = ReadMCURegisters((ushort)MCUConstants.MCUOutputRegs.NetworkConnectivity, 1);
+
+ // If the network status length is 50, it means the network has disconnected, and we must attempt to reconnect
+ if (networkStatus.Length == 50)
+ {
+ // Only try to connect if it's been more than 5 seconds since the last attempt
+ if ((DateTime.Now - lastConnectAttempt) > TimeSpan.FromSeconds(5))
+ {
+ if (!inError)
+ {
+ logger.Error(Utilities.GetTimeStamp() + ": The MCU failed to retrieve the register data, and is either offline or the connection has been terminated.");
+ inError = true;
+ logger.Info(Utilities.GetTimeStamp() + ": Attempting to connect to the MCU...");
+ }
+ ConnectToModbusServer();
+ lastConnectAttempt = DateTime.Now;
+ }
+ }
+ else
+ {
+ // This heartbeat bit flips between 0 and 1 every 500ms to ensure that the MCU is still alive
+ // and doing MCU stuff
+ int currentHeartBeat = (networkStatus[0] >> (ushort)MCUNetworkStatus.MCUHeartBeat) & 1;
+ if (currentHeartBeat != lastHeartBeat)
+ {
+ MCU_last_contact = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
+ lastHeartBeat = currentHeartBeat;
+ }
+
+ // This bit is used to tell when the control room has reconnected to the MCU after being
+ // disconnected
+ if (((networkStatus[0] >> (ushort)MCUNetworkStatus.MCUNetworkDisconnected) & 1) == 1)
+ {
+ inError = false;
+ }
+ }
+
+ Task.Delay(250).Wait();
+ }
+ }
+
+ ///
+ /// Starts the MCU heartbeat monitor thread.
+ ///
+ /// Boolean denoting whether the thread was started successfully or not.
+ public bool StartAsyncAcceptingClients() {
+ HeartbeatMonitorRunning = true;
+
+ try
+ {
+ HeartbeatMonitorThread.Start();
+ }
+ catch (Exception e)
+ {
+ if((e is ThreadStateException) || (e is OutOfMemoryException))
+ {
+ logger.Error(Utilities.GetTimeStamp() + ": Failed to start the MCU heartbeat monitor thread. Please restart the Control Room software.");
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ ///
+ /// kills the MCU monitor thread
+ ///
+ ///
+ public bool RequestStopAsyncAcceptingClientsAndJoin() {
+ HeartbeatMonitorRunning = false;
+ try {
+ HeartbeatMonitorThread.Join();
+ } catch(Exception e) {
+ if((e is ThreadStateException) || (e is ThreadStartException)) {
+ logger.Error(Utilities.GetTimeStamp() + ": " + e);
+ return false;
+ } else { throw e; }// Unexpected exception
+ }
+ return true;
+ }
+
+ ///
+ /// Reads the position from the motor encoders.
+ ///
+ ///
+ public Orientation GetMotorEncoderPosition() {
+
+ ushort[] data = ReadMCURegisters(0, 16);
+
+ int azMotorEncoderTicks = (data[(ushort)MCUOutputRegs.AZ_MTR_Encoder_Pos_MSW] << 16) + data[(ushort)MCUOutputRegs.AZ_MTR_Encoder_Pos_LSW];
+ int elMotorEncoderTicks = -((data[(ushort)MCUOutputRegs.EL_MTR_Encoder_Pos_MSW] << 16) + data[(ushort)MCUOutputRegs.EL_MTR_Encoder_Pos_LSW]);
+
+ // If the telescope type is SLIP_RING, we want to normalize the azimuth orientation
+ if (telescopeType == RadioTelescopeTypeEnum.SLIP_RING)
+ {
+ return new Orientation(
+ ConversionHelper.StepsToDegrees_Encoder_Normalized(azMotorEncoderTicks, MotorConstants.GEARING_RATIO_AZIMUTH),
+ ConversionHelper.StepsToDegrees_Encoder(elMotorEncoderTicks, MotorConstants.GEARING_RATIO_ELEVATION)
+ );
+ }
+ else
+ {
+ return new Orientation(
+ ConversionHelper.StepsToDegrees_Encoder(azMotorEncoderTicks, MotorConstants.GEARING_RATIO_AZIMUTH),
+ ConversionHelper.StepsToDegrees_Encoder(elMotorEncoderTicks, MotorConstants.GEARING_RATIO_ELEVATION)
+ );
+ }
+ }
+
+ ///
+ /// gets the position from MCU step count, thsi should be compaired with the value from
+ ///
+ ///
+ /// the MCU traks 2 values for position one that comes from the encoder mounted on the motors shaft,
+ /// the other comes from the MCU keeping track of howmany steps it has told the motor to take
+ /// if these numbers get out of sync that means the motors are missing steps and are experiencing a high load,
+ /// there are 8_000 encoder counts per revolution of the motor and 20_000 steeps from the MCU so the exact numbers wont match up
+ /// also there will always be some play in the position that the encoder reports +-10 counts should be within acceptabele limts
+ ///
+ ///
+ public Orientation GetMotorStepsPosition() {
+ ushort[] data = ReadMCURegisters(0, 16);
+
+ int azSteps = (data[(ushort)MCUOutputRegs.AZ_Current_Position_MSW] << 16) + data[(ushort)MCUOutputRegs.AZ_Current_Position_LSW];
+ int elSteps = -((data[(ushort)MCUOutputRegs.EL_Current_Position_MSW] << 16) + data[(ushort)MCUOutputRegs.EL_Current_Position_LSW]);
+
+ // If the telescope type is SLIP_RING, we want to normalize the azimuth orientation
+ if (telescopeType == RadioTelescopeTypeEnum.SLIP_RING)
+ {
+ return new Orientation(
+ ConversionHelper.StepsToDegrees_Normalized(azSteps, MotorConstants.GEARING_RATIO_AZIMUTH),
+ ConversionHelper.StepsToDegrees(elSteps, MotorConstants.GEARING_RATIO_ELEVATION)
+ );
+ }
+ else
+ {
+ return new Orientation(
+ ConversionHelper.StepsToDegrees(azSteps, MotorConstants.GEARING_RATIO_AZIMUTH),
+ ConversionHelper.StepsToDegrees(elSteps, MotorConstants.GEARING_RATIO_ELEVATION)
+ );
+ }
+ }
+
+ ///
+ /// clears the previos move comand from mthe PLC, only works for jog moves
+ ///
+ ///
+ public MovementResult Cancel_move() {
+ MovementResult success = MovementResult.None;
+
+ // Build command to clear both axes registers
+ var cmd = new MCUCommand(MCUMessages.ClearBothAxesMove, MCUCommandType.EmptyData) { completed = false };
+
+ // Verify that the command could be sent
+ if(!SendGenericCommand( cmd )) return MovementResult.CouldNotSendCommand;
+
+ // Determine whether stopping was a success or not
+ success = WaitUntilStopped();
+ cmd.completed = true;
+
+ return success;
+ }
+
+ ///
+ /// Attempts to bring the Telescope to a controlled stop, ramping down speed.
+ /// Certian moves, such as homing, are unaffected by this.
+ ///
+ ///
+ public MovementResult ControlledStop() {
+ MovementResult success = MovementResult.None;
+
+ // Jog movements must be stopped differently than other movements
+ if(RunningCommand.CommandType == MCUCommandType.Jog) {
+ success = Cancel_move();
+ } else {
+ var cmd = new MCUCommand(MCUMessages.HoldMove , MCUCommandType.HoldMove) { completed = false };
+ if (!SendGenericCommand(cmd)) return MovementResult.CouldNotSendCommand;
+ success = WaitUntilStopped();
+ cmd.completed = true;
+ }
+ return success;
+ }
+
+ ///
+ /// Immediately stops the telescope movement with no ramp down in speed.
+ /// Homing is unaffected by this command.
+ ///
+ ///
+ public MovementResult ImmediateStop() {
+ if (!SendGenericCommand(new MCUCommand(MCUMessages.ImmediateStop, MCUCommandType.ImmediateStop) { completed = true }))
+ return MovementResult.CouldNotSendCommand;
+
+ return MovementResult.Success;
+ }
+
+ // This only resets command errors
+ private void CheckForAndResetCommandErrors() {
+
+ // Registers 0 and 11 are the most significant words fo the azimuth and elevation statuses
+ var data = ReadMCURegisters(0, 11);
+
+ bool azCmdErr = ((data[(int)MCUConstants.MCUOutputRegs.AZ_Status_Bist_MSW] >> (int)MCUConstants.MCUStatusBitsMSW.Command_Error) & 0b1) == 1;
+ bool elCmdErr = ((data[(int)MCUConstants.MCUOutputRegs.EL_Status_Bist_MSW] >> (int)MCUConstants.MCUStatusBitsMSW.Command_Error) & 0b1) == 1;
+
+ if(elCmdErr || azCmdErr) {
+ ResetMCUErrors();
+ }
+ }
+
+ ///
+ /// Resets any errors the MCU encounters. This could be for either of the motors.
+ ///
+ public void ResetMCUErrors()
+ {
+ SendGenericCommand(new MCUCommand(MCUMessages.ResetErrors, MCUCommandType.ClearErrors) { completed = true });
+ }
+
+ ///
+ /// Checks the MCU registers for any errors
+ ///
+ /// Returns all errors that were found.
+ public List> CheckMCUErrors()
+ {
+ var data = ReadMCURegisters(0, 12);
+
+ // We will be storing the values in pairs so we can see which status bit has which error
+ List> errors = new List>();
+
+ // Loop through every MCU output register and check for errors
+ for(int i = 0; i <= 11; i++)
+ {
+ // If the register contains an error, add it to the output list
+ // We are only interested in output registers 0, 1, 10 and 11, which contain the
+ // azimuth and elevation motor errors
+
+ // Home invalid errors
+ if ((i == 0 || i == 1 || i == 10 || i == 11) && ((data[i] >> (int)MCUStatusBitsMSW.Home_Invalid_Error) & 0b1) == 1)
+ errors.Add(new Tuple((MCUOutputRegs)i, MCUStatusBitsMSW.Home_Invalid_Error));
+
+ // Profile invalid errors
+ if ((i == 0 || i == 1 || i == 10 || i == 11) && ((data[i] >> (int)MCUStatusBitsMSW.Profile_Invalid) & 0b1) == 1)
+ errors.Add(new Tuple((MCUOutputRegs)i, MCUStatusBitsMSW.Profile_Invalid));
+
+ // Input error
+ if ((i == 0 || i == 1 || i == 10 || i == 11) && ((data[i] >> (int)MCUStatusBitsMSW.Input_Error) & 0b1) == 1)
+ errors.Add(new Tuple((MCUOutputRegs)i, MCUStatusBitsMSW.Input_Error));
+
+ // Command errors
+ if ((i == 0 || i == 1 || i == 10 || i == 11) && ((data[i] >> (int)MCUStatusBitsMSW.Command_Error) & 0b1) == 1)
+ errors.Add(new Tuple((MCUOutputRegs)i, MCUStatusBitsMSW.Command_Error));
+
+ // Configuration error
+ if ((i == 0 || i == 1 || i == 10 || i == 11) && ((data[i] >> (int)MCUStatusBitsMSW.Configuration_Error) & 0b1) == 1)
+ errors.Add(new Tuple((MCUOutputRegs)i, MCUStatusBitsMSW.Configuration_Error));
+ }
+
+ return errors;
+ }
+
+ ///
+ /// This function assumes that you have already told both axes to stop moving, otherwise it will time out.
+ ///
+ /// False if the telescope is still moving at the end of the timeout.
+ private MovementResult WaitUntilStopped()
+ {
+ int mS_To_Decelerate = Math.Abs(estimateStopTime(PreviousCommand));
+ var timout = new CancellationTokenSource( mS_To_Decelerate ).Token;
+ while(!timout.IsCancellationRequested) {
+ Task.Delay( 33 ).Wait();
+ if(!MotorsCurrentlyMoving()) {
+ return MovementResult.Success;
+ }
+ }
+ return MovementResult.TimedOut;
+
+ }
+
+ private int estimateStopTime( MCUCommand CMD ) {
+ int mS_To_DecelerateAZ = (int)1.25 * (CMD.AzimuthSpeed - AZStartSpeed) / CMD.AZ_ACC;
+ int mS_To_DecelerateEL = (int)1.25 * (CMD.ElevationSpeed - AZStartSpeed) / CMD.EL_ACC;
+ int mS_To_Decelerate;
+ if(mS_To_DecelerateAZ > mS_To_DecelerateEL) {
+ mS_To_Decelerate = mS_To_DecelerateAZ;
+ } else {
+ mS_To_Decelerate = mS_To_DecelerateEL;
+ }
+ return mS_To_Decelerate;
+ }
+
+ private Orientation estimateDistanceToStop( MCUCommand CMD ) {
+ int StepsAZ = 0, StepsEL = 0;
+ if(CMD.AzimuthSpeed > 0) {
+ int mS_To_DecelerateAZ = (int)((1.25 * (CMD.AzimuthSpeed - AZStartSpeed) / (double)CMD.AZ_ACC) / 1000.0);
+ StepsAZ = (int)(mS_To_DecelerateAZ * ((CMD.AzimuthSpeed + ConversionHelper.RPMToSPS( Current_AZConfiguration.StartSpeed , MotorConstants.GEARING_RATIO_AZIMUTH )) / 2.0));
+ StepsAZ += (int)(CMD.AzimuthSpeed * 0.25);//add 100 ms worth of steps
+ if(CMD.AzimuthDirection == RadioTelescopeDirectionEnum.CounterclockwiseOrPositive) {
+ StepsAZ = -StepsAZ;
+ }
+ }
+ if(CMD.ElevationSpeed > 0) {
+ int mS_To_DecelerateEL = (int)((1.25 * (CMD.ElevationSpeed - AZStartSpeed) / (double)CMD.EL_ACC) / 1000.0);
+ StepsEL = (int)(mS_To_DecelerateEL * ((CMD.ElevationSpeed + ConversionHelper.RPMToSPS( Current_ELConfiguration.StartSpeed , MotorConstants.GEARING_RATIO_ELEVATION )) / 2.0));
+ StepsEL += (int)(CMD.ElevationSpeed * 0.25);//add 100 ms worth of steps
+ if(CMD.ElevationDirection == RadioTelescopeDirectionEnum.CounterclockwiseOrPositive) {
+ StepsEL = -StepsEL;
+ }
+ }
+ return new Orientation( ConversionHelper.StepsToDegrees( StepsAZ , MotorConstants.GEARING_RATIO_AZIMUTH ) , ConversionHelper.StepsToDegrees( StepsEL , MotorConstants.GEARING_RATIO_ELEVATION ) );
+ }
+
+ ///
+ /// This function assumes that you have already told both Axes to stop moving, otherwise it will time out.
+ ///
+ /// False if the telescope was still running at the end of the timeout
+ private bool WaitUntilStoppedPerAxis(RadioTelescopeAxisEnum axis) {
+
+ int msToDecelerate = 0;
+
+ // Calculate timeout based on the axis
+ if(axis == RadioTelescopeAxisEnum.AZIMUTH) {
+ msToDecelerate = (int)1.25 * (PreviousCommand.AzimuthSpeed - AZStartSpeed) / PreviousCommand.AZ_ACC;
+ } else {
+ msToDecelerate = (int)1.25 * (PreviousCommand.ElevationSpeed - ELStartSpeed) / PreviousCommand.EL_ACC;
+ }
+
+ CancellationToken timeout = new CancellationTokenSource(msToDecelerate).Token;
+
+ // Wait for the axis to stop. If it takes longer than the estimated time to decelerate, then
+ // the movement failed and we return false.
+ try
+ {
+ while (!timeout.IsCancellationRequested)
+ {
+ if (!MotorsCurrentlyMoving(axis))
+ {
+ return true;
+ }
+ }
+ }
+ catch
+ {
+ return false;
+ }
+
+ return false;
+
+ }
+
+ ///
+ /// Tells us if the motors are currently moving. This will automatically return if both motors are moving
+ /// if no parameter is passed through.
+ ///
+ ///
+ /// This code could, technically, be shortened so we read all the registers in the beginning and decide
+ /// what to do with them in the switch, but my idea here was to only read the registers we need to ensure
+ /// the fastest possible execution time.
+ ///
+ /// The axis we want to check is moving.
+ /// True if they are moving clockwise or counter-clockwise, false if they are still.
+ public bool MotorsCurrentlyMoving(RadioTelescopeAxisEnum axis = RadioTelescopeAxisEnum.BOTH) {
+
+ bool isMoving = false;
+ ushort[] data;
+
+ switch(axis)
+ {
+ case RadioTelescopeAxisEnum.AZIMUTH:
+ // Only read the registers we need
+ data = ReadMCURegisters(0, 1);
+
+ // Check if the azimuth motor is spinning clockwise or counter-clockwise
+ isMoving = (((data[(int)MCUConstants.MCUOutputRegs.AZ_Status_Bist_MSW] >> (int)MCUConstants.MCUStatusBitsMSW.CCW_Motion) & 0b1) == 1) ||
+ (((data[(int)MCUConstants.MCUOutputRegs.AZ_Status_Bist_MSW] >> (int)MCUConstants.MCUStatusBitsMSW.CW_Motion) & 0b1) == 1);
+ break;
+
+ case RadioTelescopeAxisEnum.ELEVATION:
+ // Only read the registers we need
+ data = ReadMCURegisters(10, 1);
+ isMoving = (((data[(int)MCUConstants.MCUOutputRegs.EL_Status_Bist_MSW] >> (int)MCUConstants.MCUStatusBitsMSW.CCW_Motion) & 0b1) == 1) ||
+ (((data[(int)MCUConstants.MCUOutputRegs.EL_Status_Bist_MSW] >> (int)MCUConstants.MCUStatusBitsMSW.CW_Motion) & 0b1) == 1);
+ break;
+
+ case RadioTelescopeAxisEnum.BOTH:
+ // Now we need to capture some more registers to get both az and el
+ data = ReadMCURegisters(0, 11);
+
+ bool azMoving = (((data[(int)MCUConstants.MCUOutputRegs.AZ_Status_Bist_MSW] >> (int)MCUConstants.MCUStatusBitsMSW.CCW_Motion) & 0b1) == 1) ||
+ (((data[(int)MCUConstants.MCUOutputRegs.AZ_Status_Bist_MSW] >> (int)MCUConstants.MCUStatusBitsMSW.CW_Motion) & 0b1) == 1);
+
+ bool elMoving = (((data[(int)MCUConstants.MCUOutputRegs.EL_Status_Bist_MSW] >> (int)MCUConstants.MCUStatusBitsMSW.CCW_Motion) & 0b1) == 1) ||
+ (((data[(int)MCUConstants.MCUOutputRegs.EL_Status_Bist_MSW] >> (int)MCUConstants.MCUStatusBitsMSW.CW_Motion) & 0b1) == 1);
+
+ // Check if azimuth or elevation are moving
+ isMoving = azMoving || elMoving;
+
+ break;
+ }
+
+ return isMoving;
+ }
+
+ ///
+ /// Will read the MCU bits to tell whether a movement has completed or not.
+ ///
+ /// What axis you want to know the completion status of.
+ /// Whether an axis' movement has completed or not.
+ public bool MovementCompleted(RadioTelescopeAxisEnum axis = RadioTelescopeAxisEnum.BOTH)
+ {
+ bool isFinished = false;
+ ushort[] data;
+
+ switch (axis)
+ {
+ case RadioTelescopeAxisEnum.AZIMUTH:
+ // Only read the registers we need
+ data = ReadMCURegisters(0, 1);
+ isFinished = ((data[(int)MCUConstants.MCUOutputRegs.AZ_Status_Bist_MSW] >> (int)MCUConstants.MCUStatusBitsMSW.Move_Complete) & 0b1) == 1;
+ break;
+
+ case RadioTelescopeAxisEnum.ELEVATION:
+ // Only read the registers we need
+ data = ReadMCURegisters(10, 1);
+ isFinished = ((data[(int)MCUConstants.MCUOutputRegs.EL_Status_Bist_MSW] >> (int)MCUConstants.MCUStatusBitsMSW.Move_Complete) & 0b1) == 1;
+ break;
+
+ case RadioTelescopeAxisEnum.BOTH:
+ data = ReadMCURegisters(0, 11);
+ bool azFinished = ((data[(int)MCUConstants.MCUOutputRegs.AZ_Status_Bist_MSW] >> (int)MCUConstants.MCUStatusBitsMSW.Move_Complete) & 0b1) == 1;
+ bool elFinished = ((data[(int)MCUConstants.MCUOutputRegs.EL_Status_Bist_MSW] >> (int)MCUConstants.MCUStatusBitsMSW.Move_Complete) & 0b1) == 1;
+
+ // Check if azimuth or elevation are finished with their movements
+ isFinished = azFinished && elFinished;
+ break;
+ }
+
+ return isFinished;
+ }
+
+ public bool Configure_MCU(MCUConfigurationAxys AZconfig , MCUConfigurationAxys ELconfig) {
+ Current_AZConfiguration = AZconfig;
+ Current_ELConfiguration = ELconfig;
+ int gearedSpeedAZ = ConversionHelper.RPMToSPS( AZconfig.StartSpeed , MotorConstants.GEARING_RATIO_AZIMUTH );
+ int gearedSpeedEL = ConversionHelper.RPMToSPS( ELconfig.StartSpeed , MotorConstants.GEARING_RATIO_ELEVATION );
+ AZStartSpeed = gearedSpeedAZ;
+ ELStartSpeed = gearedSpeedEL;
+ TestDefaultParams( AZconfig.StartSpeed , ELconfig.StartSpeed , AZconfig.HomeTimeoutSec , ELconfig.HomeTimeoutSec );
+ ushort[] data = { MakeMcuConfMSW(AZconfig), MakeMcuConfLSW(AZconfig) , (ushort)(gearedSpeedAZ >> 0x0010), (ushort)(gearedSpeedAZ & 0xFFFF), 0x0,0x0,0x0,0x0,0x0,0x0,
+ MakeMcuConfMSW(ELconfig), MakeMcuConfLSW(ELconfig), (ushort)(gearedSpeedEL >> 0x0010), (ushort)(gearedSpeedEL & 0xFFFF), 0x0,0x0,0x0,0x0,0x0,0x0 };
+ ImmediateStop();
+ SendGenericCommand( new MCUCommand( data , MCUCommandType.Configure) { completed = true} );
+
+ // Allow the MCU to configure
+ Thread.Sleep(250);
+
+ // If there are any errors present, return false
+ if (CheckMCUErrors().Count > 0) return false;
+ return true;
+ }
+
+ private ushort MakeMcuConfMSW(MCUConfigurationAxys AxysConf) {
+ ushort conf = 0x8400;//first byte should be 84 for current hardware setup
+ switch (AxysConf.CWinput) {
+ case CW_CCW_input_use.LimitSwitch:
+ conf = (ushort)(conf | 0b000_1000);
+ break;
+ case CW_CCW_input_use.EStop:
+ conf = (ushort)(conf | 0b001_0000);
+ break;
+ }
+ switch (AxysConf.CCWinput) {
+ case CW_CCW_input_use.LimitSwitch:
+ conf = (ushort)(conf | 0b0010_0000);
+ break;
+ case CW_CCW_input_use.EStop:
+ conf = (ushort)(conf | 0b0100_0000);
+ break;
+ }
+ switch(AxysConf.EncoderType) {
+ case EncoderTyprEnum.Quadrature_Encoder:
+ conf = (ushort)(conf | 0b1_0000_0000);
+ break;
+ case EncoderTyprEnum.Diagnostic_Feedback:
+ conf = (ushort)(conf | 0b10_0000_0000);
+ break;
+ }
+ if (AxysConf.UseHomesensors) {
+ conf = (ushort)(conf | 0b0100);
+ }
+ if(AxysConf.UseCapture) {
+ conf = (ushort)(conf | 0b0001);
+ }
+ return conf;
+ }
+
+ private ushort MakeMcuConfLSW(MCUConfigurationAxys AxysConf) {
+ ushort conf = 0x0000;
+ if(AxysConf.CaptureActive_High) {
+ conf = (ushort)(conf | 0b0001);
+ }
+ if (AxysConf.HomeActive_High) {
+ conf = (ushort)(conf | 0b0_0100);
+ }
+ if (AxysConf.CWactive_High) {
+ conf = (ushort)(conf | 0b0_1000);
+ }
+ if (AxysConf.CCWactive_High) {
+ conf = (ushort)(conf | 0b1_0000);
+ }
+ return conf;
+ }
+
+ private void TestDefaultParams(double startSpeedDPSAzimuth, double startSpeedDPSElevation, int homeTimeoutSecondsAzimuth, int homeTimeoutSecondsElevation) {
+ int gearedSpeedAZ = ConversionHelper.DPSToSPS(startSpeedDPSAzimuth, MotorConstants.GEARING_RATIO_AZIMUTH);
+ int gearedSpeedEL = ConversionHelper.DPSToSPS(startSpeedDPSElevation, MotorConstants.GEARING_RATIO_ELEVATION);
+ Console.WriteLine(gearedSpeedAZ.ToString() + " :AZ EL:" + gearedSpeedEL.ToString());
+ if ((gearedSpeedEL < 1) || (gearedSpeedEL > MCUConstants.ACTUAL_MCU_DEFAULT_PEAK_VELOCITY)) {
+ throw new ArgumentOutOfRangeException("startSpeedDPSElevation", startSpeedDPSElevation,
+ String.Format("startSpeedDPSElevation should be between {0} and {1}",
+ ConversionHelper.SPSToDPS(1, MotorConstants.GEARING_RATIO_ELEVATION),
+ ConversionHelper.SPSToDPS(MCUConstants.ACTUAL_MCU_DEFAULT_PEAK_VELOCITY, MotorConstants.GEARING_RATIO_ELEVATION)));
+ }
+ if ((gearedSpeedAZ < 1) || (gearedSpeedAZ > MCUConstants.ACTUAL_MCU_DEFAULT_PEAK_VELOCITY)) {
+ throw new ArgumentOutOfRangeException("startSpeedDPSAzimuth", startSpeedDPSAzimuth,
+ String.Format("startSpeedDPSAzimuth should be between {0} and {1}",
+ ConversionHelper.SPSToDPS(1, MotorConstants.GEARING_RATIO_AZIMUTH),
+ ConversionHelper.SPSToDPS(MCUConstants.ACTUAL_MCU_DEFAULT_PEAK_VELOCITY, MotorConstants.GEARING_RATIO_AZIMUTH)));
+ }
+ if ((homeTimeoutSecondsElevation < 0) || (homeTimeoutSecondsElevation > 300)) {
+ throw new ArgumentOutOfRangeException("homeTimeoutSecondsElevation", homeTimeoutSecondsElevation,
+ String.Format("homeTimeoutSecondsElevation should be between {0} and {1}", 0, 300));
+ }
+ if ((homeTimeoutSecondsAzimuth < 0) || (homeTimeoutSecondsAzimuth > 300)) {
+ throw new ArgumentOutOfRangeException("homeTimeoutSecondsAzimuth", homeTimeoutSecondsAzimuth,
+ String.Format("homeTimeoutSecondsAzimuth should be between {0} and {1}", 0, 300));
+ }
+ }
+
+ ///
+ /// Sends a home command and waits for the MCU to finish homing.
+ ///
+ ///
+ ///
+ public MovementResult HomeBothAxes(double RPM) {
+
+ int EL_Speed = ConversionHelper.DPSToSPS( ConversionHelper.RPMToDPS( RPM ) , MotorConstants.GEARING_RATIO_ELEVATION );
+ int AZ_Speed = ConversionHelper.DPSToSPS( ConversionHelper.RPMToDPS( RPM ) , MotorConstants.GEARING_RATIO_AZIMUTH );
+
+ //set config word to 0x0040 to have the RT home at the minimumum speed// this requires the MCU to be configured properly
+ ushort[] data = {
+ // azimuth data
+ (ushort)RadioTelescopeDirectionEnum.CounterclockwiseHoming,
+ (ushort)MCUCommandType.EmptyData,
+ (ushort)MCUCommandType.EmptyData,
+ (ushort)MCUCommandType.EmptyData,
+ (ushort)((AZ_Speed & 0xFFFF0000)>>16),
+ (ushort)(AZ_Speed & 0xFFFF),
+ ACTUAL_MCU_MOVE_ACCELERATION_WITH_GEARING,
+ ACTUAL_MCU_MOVE_ACCELERATION_WITH_GEARING,
+ (ushort)MCUCommandType.EmptyData,
+ (ushort)MCUCommandType.EmptyData,
+
+ // elevation data
+ (ushort)RadioTelescopeDirectionEnum.CounterclockwiseHoming,
+ (ushort)MCUCommandType.EmptyData,
+ (ushort)MCUCommandType.EmptyData,
+ (ushort)MCUCommandType.EmptyData,
+ (ushort)((EL_Speed & 0xFFFF0000)>>16),
+ (ushort)(EL_Speed & 0xFFFF),
+ ACTUAL_MCU_MOVE_ACCELERATION_WITH_GEARING,
+ ACTUAL_MCU_MOVE_ACCELERATION_WITH_GEARING,
+ (ushort)MCUCommandType.EmptyData,
+ (ushort)MCUCommandType.EmptyData
+ };
+
+ // Calculate which axis has the longest timeout, then set the timeout as that axis
+ int timeout;
+ if(Current_AZConfiguration.HomeTimeoutSec > Current_ELConfiguration.HomeTimeoutSec) {
+ timeout = Current_AZConfiguration.HomeTimeoutSec;
+ } else {
+ timeout = Current_ELConfiguration.HomeTimeoutSec;
+ }
+
+ // Builds the MCU command and then sends it
+ MCUCommand command = new MCUCommand(data, MCUCommandType.Home)
+ {
+ AzimuthSpeed = AZ_Speed,
+ ElevationSpeed = EL_Speed,
+ EL_ACC = ACTUAL_MCU_MOVE_ACCELERATION_WITH_GEARING,
+ AZ_ACC = ACTUAL_MCU_MOVE_ACCELERATION_WITH_GEARING,
+ timeout = new CancellationTokenSource((int)(timeout * 1200)) //* 1000 for seconds to ms //* 1.2 for a 20% margin
+ };
+
+ // If sending the command fails, return because the movement cannot complete.
+ if(!SendGenericCommand(command)) return MovementResult.CouldNotSendCommand;
+
+ // The new orientation is 0,0 because homing should result in the motor encoders being zeroed out
+ return MovementMonitor(command, new Orientation(0,0), true);
+ }
+
+ private bool BuildAndSendRelativeMove(MCUCommand command, int positionTranslationAz, int positionTranslationEl) {
+ bool success = false;
+
+ if (command.AzimuthSpeed < AZStartSpeed) {
+ throw new ArgumentOutOfRangeException("SpeedAZ", command.AzimuthSpeed,
+ String.Format("Azimuth speed should be greater than {0}, which is the starting speed set when configuring the MCU", AZStartSpeed));
+ }
+ if (command.ElevationSpeed < ELStartSpeed) {
+ throw new ArgumentOutOfRangeException("SpeedEL", command.ElevationSpeed,
+ String.Format("Elevation speed should be greater than {0}, which is the starting speed set when configuring the MCU", ELStartSpeed));
+ }
+
+ // This needs flipped so that the elevation axis moves the correct direction
+ positionTranslationEl = -positionTranslationEl;
+
+ command.commandData = new ushort[] {
+ // Azimuth data
+ (ushort)MCUCommandType.RelativeMove,
+ 0x0003,
+ (ushort)((positionTranslationAz & 0xFFFF0000)>>16),
+ (ushort)(positionTranslationAz & 0xFFFF),
+ (ushort)((command.AzimuthSpeed & 0xFFFF0000)>>16),
+ (ushort)(command.AzimuthSpeed & 0xFFFF),
+ ACTUAL_MCU_MOVE_ACCELERATION_WITH_GEARING,
+ ACTUAL_MCU_MOVE_ACCELERATION_WITH_GEARING,
+ (ushort)MCUCommandType.EmptyData,
+ (ushort)MCUCommandType.EmptyData,
+
+ // Elevation data
+ (ushort)MCUCommandType.RelativeMove,
+ 0x0003,
+ (ushort)((positionTranslationEl & 0xFFFF0000)>>16),
+ (ushort)(positionTranslationEl & 0xFFFF),
+ (ushort)((command.ElevationSpeed & 0xFFFF0000)>>16),
+ (ushort)(command.ElevationSpeed & 0xFFFF),
+ ACTUAL_MCU_MOVE_ACCELERATION_WITH_GEARING,
+ ACTUAL_MCU_MOVE_ACCELERATION_WITH_GEARING,
+ (ushort)MCUCommandType.EmptyData,
+ (ushort)MCUCommandType.EmptyData
+ };
+
+ RunningCommand = command;
+ success = WriteMCURegisters(command.commandData);
+
+ // Give the MCU time to process the data
+ Thread.Sleep(100);
+
+ return success;
+ }
+
+ ///
+ /// perform the specified move and wait for it to be completted by the telescope
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public MovementResult MoveAndWaitForCompletion(int SpeedAZ, int SpeedEL, int positionTranslationAZ, int positionTranslationEL,
+ Orientation targetOrientation)
+ {
+ // Clear any leftover register data
+ Cancel_move();
+
+ // Estimate the time to move, which will be the axis that takes the longest
+ int AZTime = EstimateMovementTime(SpeedAZ, positionTranslationAZ);
+ int ELTime = EstimateMovementTime(SpeedEL, positionTranslationEL);
+ int TimeToMove;
+ if(AZTime > ELTime) {
+ TimeToMove = AZTime;
+ } else { TimeToMove = ELTime; }
+
+ // Add on some extra time so the timeout doesn't end early
+ TimeToMove = ( int)(TimeToMove * 1.2);
+ TimeToMove += 100;
+
+ if (targetOrientation.Azimuth == 0.0 || targetOrientation.Azimuth==360.0) TimeToMove += 100;
+
+
+ // Calculate azimuth movement direction
+ RadioTelescopeDirectionEnum azDirection;
+ if (positionTranslationAZ > 0) azDirection = RadioTelescopeDirectionEnum.ClockwiseOrNegative;
+ else azDirection = RadioTelescopeDirectionEnum.CounterclockwiseOrPositive;
+
+ // Calculate elevation movement direction
+ RadioTelescopeDirectionEnum elDirection;
+ if (positionTranslationEL > 0) elDirection = RadioTelescopeDirectionEnum.CounterclockwiseOrPositive;
+ else elDirection = RadioTelescopeDirectionEnum.ClockwiseOrNegative;
+
+ // Build and send the MCU Command (the data is the only part sent to the MCU; the rest is for inner tracking)
+ MCUCommand ThisMove =
+ new MCUCommand(
+ new ushort[0],
+ MCUCommandType.RelativeMove,
+ azDirection,
+ elDirection,
+ SpeedAZ,
+ SpeedEL
+ )
+ {
+ EL_ACC = ACTUAL_MCU_MOVE_ACCELERATION_WITH_GEARING,
+ AZ_ACC = ACTUAL_MCU_MOVE_ACCELERATION_WITH_GEARING,
+ timeout = new CancellationTokenSource(TimeToMove)
+ };
+
+ // Build command data
+ // If the command could not be sent, return
+ if(!BuildAndSendRelativeMove(
+ ThisMove,
+ positionTranslationAZ,
+ positionTranslationEL
+ ))
+ {
+ return MovementResult.CouldNotSendCommand;
+ }
+
+ return MovementMonitor(ThisMove, targetOrientation);
+ }
+
+ ///
+ /// This will loop through and monitor MCU movement as long as the following conditions are true:
+ /// Cannot be timed out
+ /// Interrupt flag must be false
+ /// No MCU errors
+ /// The movement result cannot have been set yet. As soon as it is set, the routine ends.
+ ///
+ ///
+ /// I don't like having "homing or not homing" in a bool, because the homing routine should technically have
+ /// its own monitoring routine (as well as every other movement), but it's legacy at this point, and unless
+ /// we plan on adding more movements down the road, I would say it's not worth changing.
+ ///
+ ///
+ ///
+ /// Tells us whether we are monitoring homing or a relative move
+ ///
+ private MovementResult MovementMonitor(MCUCommand command, Orientation targetOrientation, bool homing = false)
+ {
+ MovementResult result = MovementResult.None;
+ bool completed = false;
+
+ while (!command.timeout.IsCancellationRequested && !MovementInterruptFlag && CheckMCUErrors().Count == 0 && result == MovementResult.None)
+ {
+ // We must wait for the MCU registers to be set before trying to read them
+ Thread.Sleep(100);
+
+ // Anything but homing...
+ if (!homing) completed = MovementCompleted();
+
+ // How we tell if homing completed...
+ else
+ {
+ // Check the At_Home bit and see if it's true
+ ushort[] data = ReadMCURegisters(0, 1);
+ completed = ((data[(int)MCUConstants.MCUOutputRegs.AZ_Status_Bist_MSW] >> (int)MCUConstants.MCUStatusBitsMSW.At_Home) & 0b1) == 1;
+ }
+
+ if (completed && !MotorsCurrentlyMoving() && !MovementInterruptFlag)
+ {
+ Thread.Sleep(200);
+ // If this is reached, the motors have stopped and we are now checking that the orientation is correct
+ Orientation encoderOrientation = GetMotorEncoderPosition();
+ Orientation offsetOrientation = new Orientation(encoderOrientation.Azimuth + FinalPositionOffset.Azimuth, encoderOrientation.Elevation + FinalPositionOffset.Elevation);
+
+ while (offsetOrientation.Azimuth > 360) offsetOrientation.Azimuth -= 360;
+ while (offsetOrientation.Azimuth < 0) offsetOrientation.Azimuth += 360;
+
+ if ((targetOrientation.Azimuth == 0.0 || targetOrientation.Azimuth==360.0) && (offsetOrientation.Azimuth > 359.9 || offsetOrientation.Azimuth < 0.1))
+ {
+ result = MovementResult.Success;
+ }
+
+ else if (Math.Abs(offsetOrientation.Azimuth - targetOrientation.Azimuth) <= 0.1 && Math.Abs(offsetOrientation.Elevation - targetOrientation.Elevation) <= 0.1)
+ {
+ result = MovementResult.Success;
+ }
+ else
+ {
+ result = MovementResult.IncorrectPosition;
+ }
+ }
+ }
+
+ List> errors = CheckMCUErrors();
+
+ bool hitLimitSwitch =
+ errors.Contains(new Tuple(MCUOutputRegs.AZ_Status_Bist_MSW, MCUStatusBitsMSW.Input_Error)) ||
+ errors.Contains(new Tuple(MCUOutputRegs.EL_Status_Bist_MSW, MCUStatusBitsMSW.Input_Error));
+
+ // If a limit switch gets hit, this is reached. We do NOT want to stop
+ // the motors if this happens. All other errors entail stopping the motors.
+ if (hitLimitSwitch)
+ {
+ result = MovementResult.LimitSwitchOrEstopHit;
+ ResetMCUErrors();
+ }
+ else
+ {
+ // If the movement times out, this is reached
+ if (command.timeout.IsCancellationRequested)
+ {
+ result = MovementResult.TimedOut;
+ }
+
+ // If there are errors on the MCU registers, this is reached
+ else if (errors.Count > 0)
+ {
+ result = MovementResult.McuErrorBitSet;
+ }
+
+ // If the movement was voluntarily interrupted, this is reached
+ else if (MovementInterruptFlag)
+ {
+ MovementInterruptFlag = false;
+
+ // Return software-stops hit if they caused the interrupt
+ if (SoftwareStopInterruptFlag)
+ {
+ SoftwareStopInterruptFlag = false;
+ result = MovementResult.SoftwareStopHit;
+ }
+ else
+ {
+ result = MovementResult.Interrupted;
+ }
+ }
+
+ // A critical movement interrupt signals an immediate stop
+ if (CriticalMovementInterruptFlag)
+ {
+ CriticalMovementInterruptFlag = false;
+ ImmediateStop();
+ }
+ else
+ {
+ ControlledStop();
+ }
+ }
+
+ command.completed = true;
+
+ command.timeout.Cancel();
+ command.Dispose();
+
+ return result;
+ }
+
+ ///
+ /// Estimate time to complete a single motor's movement based on input values.
+ ///
+ /// The maximum number of steps per second a motor will run.
+ ///
+ /// The total number of motor steps that a movement will take.
+ /// Estimated time that a movement command will take in milliseconds.
+ public static int EstimateMovementTime(int maxVelocity, int distance) {
+ //acc steps/millisecond/second
+ distance = Math.Abs(distance);
+ maxVelocity = Math.Abs(maxVelocity);
+
+ int t1 = maxVelocity / ACTUAL_MCU_MOVE_ACCELERATION_WITH_GEARING;//ms
+
+ double t1s = t1 / 1000.0;
+
+ int distT1 = (int)(ACTUAL_MCU_MOVE_ACCELERATION_WITH_GEARING * 1000 / 2 * (t1s * t1s) * 2);
+
+ if (distT1 < distance) {
+
+ int t2 = (distance - distT1) / maxVelocity;
+
+ return t2*1000 + (2 * t1);
+
+ } else {
+ return 2 * t1;
+ }
+ }
+
+ ///
+ /// Jogs one axis, or both axes at the same time.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public MovementResult SendBothAxesJog(double AZspeed, RadioTelescopeDirectionEnum azDirection, double ELspeed, RadioTelescopeDirectionEnum elDirection) {
+
+ int AZstepSpeed = ConversionHelper.RPMToSPS( AZspeed , MotorConstants.GEARING_RATIO_AZIMUTH );
+ int ELstepSpeed = ConversionHelper.RPMToSPS( ELspeed , MotorConstants.GEARING_RATIO_ELEVATION );
+ ushort[] data = new ushort[10] { (ushort)azDirection , 0x0003 , 0x0 , 0x0 , (ushort)(AZstepSpeed >> 16) , (ushort)(AZstepSpeed & 0xffff) , MCUConstants.ACTUAL_MCU_MOVE_ACCELERATION_WITH_GEARING , MCUConstants.ACTUAL_MCU_MOVE_ACCELERATION_WITH_GEARING , 0x0 , 0x0 , };
+ ushort[] data2 = new ushort[20];
+
+ if(AZstepSpeed > AZStartSpeed) {
+ for(int j = 0; j < data.Length; j++) {
+ data2[j] = data[j];
+ }
+ } else {
+ AZstepSpeed = 0;
+ }
+
+ if(ELstepSpeed > ELStartSpeed) {
+ for(int j = 0; j < data.Length; j++) {
+ data2[j + 10] = data[j];
+ }
+
+ data2[10] = (ushort)(elDirection);
+ data2[14] = (ushort)(ELstepSpeed >> 16);
+ data2[15] = (ushort)(ELstepSpeed & 0xffff);
+ } else {
+ ELstepSpeed = 0;
+ }
+ bool booth = false;
+ if(RunningCommand.CommandType == MCUCommandType.Jog) {
+ //if telescope is already joging changing direction requires stopping first
+ ushort[] data3 = new ushort[20];
+ data2.CopyTo( data3 , 0 );
+ booth = (RunningCommand.AzimuthDirection != azDirection) && (RunningCommand.ElevationDirection != elDirection);
+ if(booth) {//if both axis need to change direction
+ Cancel_move();
+ WaitUntilStopped();
+ } else if(RunningCommand.ElevationDirection != elDirection) {//if only elevation needs to change direction
+ for(int j = 0; j <= data3.Length - 11; j++) {
+ // TODO: Replace ClearBothAxesMove with simplified code and ClearSingleAxisMove (issue #390)
+ data3[j + 10] = MCUMessages.ClearBothAxesMove[j + 10];//replace elevation portion of move with controled stop
+ }
+ if (!SendGenericCommand(new MCUCommand(data3, MCUCommandType.Jog, azDirection, elDirection, AZstepSpeed, ELstepSpeed)
+ {
+ EL_ACC = MCUConstants.ACTUAL_MCU_MOVE_ACCELERATION_WITH_GEARING,
+ })) return MovementResult.CouldNotSendCommand;
+ WaitUntilStoppedPerAxis(RadioTelescopeAxisEnum.AZIMUTH);
+ } else if(RunningCommand.AzimuthDirection != azDirection) {//only Azimuth needs to change direction
+ for(int j = 0; j <= data3.Length - 1; j++)
+ {
+ // TODO: Replace ClearBothAxesMove with simplified code and ClearSingleAxisMove (issue #390)
+ data3[j] = MCUMessages.ClearBothAxesMove[j];//replace Azimuth portion of move with controled stop
+ }
+ if (!SendGenericCommand(new MCUCommand(data3, MCUCommandType.Jog, azDirection, elDirection, AZstepSpeed, ELstepSpeed)
+ {
+ AZ_ACC = MCUConstants.ACTUAL_MCU_MOVE_ACCELERATION_WITH_GEARING,
+ })) return MovementResult.CouldNotSendCommand;
+ WaitUntilStoppedPerAxis(RadioTelescopeAxisEnum.ELEVATION);
+ }
+ }
+
+ if (!SendGenericCommand(new MCUCommand(data2, MCUCommandType.Jog, azDirection, elDirection, AZstepSpeed, ELstepSpeed)
+ {//send the portion of the jog move that was previously replaced with a controlled stop
+ EL_ACC = MCUConstants.ACTUAL_MCU_MOVE_ACCELERATION_WITH_GEARING,
+ AZ_ACC = MCUConstants.ACTUAL_MCU_MOVE_ACCELERATION_WITH_GEARING,
+ })) return MovementResult.CouldNotSendCommand;
+
+ return MovementResult.Success;
+ }
+
+ private bool SendGenericCommand(MCUCommand incoming) {
+ bool success = false;
+ RunningCommand = incoming;
+ success = WriteMCURegisters(incoming.commandData);
+ return success;
+ }
+
+ ///
+ /// This should only be used to back off of limit switches.
+ /// For any other jog moves, use the
+ ///
+ /// What axis (elevation or azimuth) is spinning.
+ /// Denotes what direction a motor will be spinning.
+ /// What speed the motor will be spinning at.
+ ///
+ public bool SendSingleAxisJog(RadioTelescopeAxisEnum axis, RadioTelescopeDirectionEnum direction, double speed) {
+ int stepSpeed;
+ bool success = false;
+
+ if(axis == RadioTelescopeAxisEnum.AZIMUTH) {
+ stepSpeed = ConversionHelper.RPMToSPS(speed, MotorConstants.GEARING_RATIO_AZIMUTH);
+ } else {
+ stepSpeed = ConversionHelper.RPMToSPS(speed, MotorConstants.GEARING_RATIO_ELEVATION);
+ }
+
+ ushort[] data = new ushort[10] {
+ (ushort)direction,
+ 0x0003,
+ (ushort)MCUCommandType.EmptyData,
+ (ushort)MCUCommandType.EmptyData,
+ (ushort)(stepSpeed >> 16),
+ (ushort)(stepSpeed & 0xffff),
+ MCUConstants.ACTUAL_MCU_MOVE_ACCELERATION_WITH_GEARING,
+ MCUConstants.ACTUAL_MCU_MOVE_ACCELERATION_WITH_GEARING,
+ (ushort)MCUCommandType.EmptyData,
+ (ushort)MCUCommandType.EmptyData
+ };
+
+ success = WriteMCURegisters(data, axis);
+
+ RunningCommand.completed = false;
+
+ return success;
+ }
+
+ ///
+ /// This should only be used to stop the jog command from backing off limit switches.
+ ///
+ /// The motor axis we are stopping.
+ ///
+ public bool StopSingleAxisJog(RadioTelescopeAxisEnum axis) {
+ WriteMCURegisters(MCUMessages.ClearOneAxisMove, axis);
+ RunningCommand.completed = true;
+ return true;
+ }
+
+ public long getLastContact() {
+ return MCU_last_contact;
+ }
+
+ ///
+ /// Sets the telescope type so we know if we should be normalizing the azimuth orientation or not.
+ ///
+ /// The telescope type we are setting the MCU manager telescope type to.
+ public void setTelescopeType(RadioTelescopeTypeEnum type)
+ {
+ telescopeType = type;
+ }
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/PLCCommunication/PLCDrivers/MCUManager/MCUMessages.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/PLCCommunication/PLCDrivers/MCUManager/MCUMessages.cs
new file mode 100644
index 00000000..c324eb88
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/PLCCommunication/PLCDrivers/MCUManager/MCUMessages.cs
@@ -0,0 +1,54 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ControlRoomApplication.Controllers.PLCCommunication.PLCDrivers.MCUManager
+{
+ ///
+ /// This contains pre-defined command data that we can send to the MCU.
+ ///
+ public sealed class MCUMessages
+ {
+ ///
+ ///
+ ///
+ public static readonly ushort[] HoldMove = new ushort[] {
+ 0x0004, 0x0003, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0004, 0x0003, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+ };
+
+ ///
+ /// Immediately stops the telescope movement.
+ ///
+ public static readonly ushort[] ImmediateStop = new ushort[] {
+ 0x0010, 0x0003, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0010, 0x0003, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+ };
+
+ ///
+ /// Clears the current movement for both motors from the registers.
+ ///
+ public static readonly ushort[] ClearBothAxesMove = new ushort[] {
+ 0x0000, 0x0003, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0003, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+ };
+
+ ///
+ /// Clears the movement for one motor from the registers
+ ///
+ public static readonly ushort[] ClearOneAxisMove = new ushort[]
+ {
+ 0x0000, 0x0003, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+ };
+
+ ///
+ /// Clears all the error registers and allows the MCU to start accepting commands again.
+ ///
+ public static readonly ushort[] ResetErrors = new ushort[] {
+ 0x0800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+ };
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/PLCCommunication/PLCDrivers/ProductionMCUDriver.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/PLCCommunication/PLCDrivers/ProductionMCUDriver.cs
deleted file mode 100644
index 20f1686d..00000000
--- a/ControlRoomApplication/ControlRoomApplication/Controllers/PLCCommunication/PLCDrivers/ProductionMCUDriver.cs
+++ /dev/null
@@ -1,614 +0,0 @@
-#define PRODUCTION_PLC_DRIVER_DEBUG
-
-using System;
-using System.Net.Sockets;
-using ControlRoomApplication.Constants;
-using ControlRoomApplication.Entities;
-using Modbus.Device;
-
-namespace ControlRoomApplication.Controllers
-{
- ///
- /// this is the driver for the MCU
- ///
- public class ProductionMCUDriver : AbstractPLCDriver
- {
- private static readonly log4net.ILog logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
-
- private TcpClient MCUTCPClient;
- public ModbusIpMaster MCUModbusMaster;
- public bool KillClientManagementThreadFlag;
- public TcpListener PLCTCPListener;
- ///
- ///
- ///
- ///
- ///
- public ProductionMCUDriver(string local_ip, string MCU_ip, int MCU_port, int PLC_port) : base(local_ip, MCU_ip, MCU_port, PLC_port)
- {
- MCUTCPClient = new TcpClient("192.168.0.50", MCUConstants.ACTUAL_MCU_MODBUS_TCP_PORT);
- MCUModbusMaster = ModbusIpMaster.CreateIp(MCUTCPClient);
- }
- ///
- ///
- ///
- ~ProductionMCUDriver()
- {
- if (MCUTCPClient != null)
- {
- MCUTCPClient.Close();
- }
- }
- ///
- ///
- ///
- ///
- public void PrintReadInputRegsiterContents(string header)
- {
-#if PRODUCTION_PLC_DRIVER_DEBUG
- System.Threading.Thread.Sleep(50);
-
- ushort[] inputRegisters = MCUModbusMaster.ReadInputRegisters(MCUConstants.ACTUAL_MCU_READ_INPUT_REGISTER_START_ADDRESS, 10);
- Console.WriteLine(header + ":");
- foreach (ushort us in inputRegisters)
- {
- string usString = Convert.ToString(us, 2);
- usString = new string('0', 16 - usString.Length) + usString;
- usString = usString.Insert(4, " ");
- usString = usString.Insert(9, " ");
- usString = usString.Insert(14, " ");
-
- Console.WriteLine('\t'.ToString() + usString);
- }
-#endif
- }
- ///
- ///
- ///
- ///
- public bool SendResetErrorsCommand()
- {
- PrintReadInputRegsiterContents("Before reset");
-
- MCUModbusMaster.WriteMultipleRegisters(MCUConstants.ACTUAL_MCU_WRITE_REGISTER_START_ADDRESS, new ushort[] { 0x0800, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 });
-
- PrintReadInputRegsiterContents("After reset");
-
- return true;
- }
- ///
- ///
- ///
- ///
- public bool SendHoldMoveCommand()
- {
- PrintReadInputRegsiterContents("Before controlled stop");
-
- MCUModbusMaster.WriteMultipleRegisters(MCUConstants.ACTUAL_MCU_WRITE_REGISTER_START_ADDRESS, new ushort[] { 0x4, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 });
-
- PrintReadInputRegsiterContents("After controlled stop");
-
- return true;
- }
- ///
- ///
- ///
- ///
- public bool SendImmediateStopCommand()
- {
- PrintReadInputRegsiterContents("Before controlled stop");
-
- MCUModbusMaster.WriteMultipleRegisters(MCUConstants.ACTUAL_MCU_WRITE_REGISTER_START_ADDRESS, new ushort[] { 0x10, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 });
-
- PrintReadInputRegsiterContents("After controlled stop");
-
- return true;
- }
- ///
- /// this stops the mcudirectly in a controld maner
- ///
- ///
- public bool SendEmptyMoveCommand()
- {
- PrintReadInputRegsiterContents("Before removing move bits");
-
- MCUModbusMaster.WriteMultipleRegisters(MCUConstants.ACTUAL_MCU_WRITE_REGISTER_START_ADDRESS, new ushort[] { 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 });
-
- PrintReadInputRegsiterContents("After removing move bits");
-
- return true;
- }
- ///
- /// configures the axies
- ///
- ///
- public bool configure_axies(int gearedSpeedAZ, int gearedSpeedEL, ushort homeTimeoutSecondsAzimuth, ushort homeTimeoutSecondsElevation)
- {
- ushort[] data = { 0x8400, 0x0000, (ushort)(gearedSpeedEL >> 0x0010), (ushort)(gearedSpeedEL & 0xFFFF), homeTimeoutSecondsElevation,
- 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x8400, 0x0000, (ushort)(gearedSpeedAZ >> 0x0010), (ushort)(gearedSpeedAZ & 0xFFFF), homeTimeoutSecondsAzimuth,
- 0x0, 0x0, 0x0, 0x0, 0x0
- };
- Console.WriteLine(data.Length);
- MCUModbusMaster.WriteMultipleRegisters(1024, data);
- return true;
- }
-
- ///
- /// this returns the orientation relative to position when the MCU configured
- ///
- ///
- public Orientation read_Position_offset()
- {
- ushort[] inputs= MCUModbusMaster.ReadHoldingRegisters(0,20);
- byte[] inbytes = new byte[inputs.Length * 2];
- Buffer.BlockCopy(inputs, 0, inbytes, 0, inputs.Length * 2);
-
- ushort msb, lsvb;
- msb = inputs[2];
- lsvb = inputs[3];
- int ofset = lsvb + (msb << 16);
- double azpos= (ofset/(20000*500))*360;
-
- msb = inputs[12];
- lsvb = inputs[13];
- ofset = lsvb + (msb << 16);
- double elpos = (ofset / (20000 * 50))*90;
-
- return new Orientation(azpos, elpos);
- //return new Orientation(BitConverter.ToDouble(inbytes, 4), BitConverter.ToDouble(inbytes, 24));
- }
-
-
- ///
- /// handle conection data comming from modbus device
- /// this serves as part of a tcp server along with HandleClientManagementThread
- /// it apears to have been designed for ethernet/ip which we found out our plc cant do
- /// this is probably unnecicary in the mcu drivers.
- ///
- ///
- ///
- ///
- public bool ProcessRequest(NetworkStream ActiveClientStream, byte[] query)
- {
- int ExpectedSize = query[0] + (256 * query[1]);
- if (query.Length != ExpectedSize)
- {
- throw new ArgumentException(
- "ProductionPLCDriver read a package specifying a size [" + ExpectedSize.ToString() + "], but the actual size was different [" + query.Length + "]."
- );
- }
-
- byte CommandQueryTypeAndExpectedResponseStatus = query[2];
- byte CommandQueryTypeByte = (byte)(CommandQueryTypeAndExpectedResponseStatus & 0x3F);
- byte ExpectedResponseStatusByte = (byte)(CommandQueryTypeAndExpectedResponseStatus >> 6);
-
- PLCCommandAndQueryTypeEnum CommandQueryTypeEnum = PLCCommandAndQueryTypeConversionHelper.GetFromByte(CommandQueryTypeByte);
- PLCCommandResponseExpectationEnum ExpectedResponseStatusEnum = PLCCommandResponseExpectationConversionHelper.GetFromByte(ExpectedResponseStatusByte);
-
- byte[] FinalResponseContainer;
-
- if (ExpectedResponseStatusEnum == PLCCommandResponseExpectationEnum.FULL_RESPONSE)
- {
- FinalResponseContainer = new byte[]
- {
- 0x13, 0x0,
- 0x0,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
- };
-
- switch (CommandQueryTypeEnum)
- {
- case PLCCommandAndQueryTypeEnum.TEST_CONNECTION:
- {
- // Read the heartbeat register
- ushort[] inputRegisters = MCUModbusMaster.ReadInputRegisters(MCUConstants.ACTUAL_MCU_READ_INPUT_REGISTER_HEARTBEAT_ADDRESS, 1);
- ushort resultValue = (ushort)((inputRegisters.Length == 1) ? inputRegisters[0] : 0);
- FinalResponseContainer[3] = (byte)(((resultValue == 8192) || (resultValue == 24576)) ? 0x1 : 0x0);
-
- FinalResponseContainer[2] = 0x1;
- break;
- }
-
- case PLCCommandAndQueryTypeEnum.GET_CURRENT_AZEL_POSITIONS:
- {
- PrintReadInputRegsiterContents("Before getting current position");
-
- // Get the MCU's value for the displacement since its power cycle
- ushort[] inputRegisters = MCUModbusMaster.ReadInputRegisters(MCUConstants.ACTUAL_MCU_READ_INPUT_REGISTER_CURRENT_POSITION_ADDRESS, 2);
- int currentStepForMCU = (65536 * inputRegisters[0]) + inputRegisters[1];
-
- PrintReadInputRegsiterContents("After getting current position");
-
- // Convert that step change into degrees and write the bytes to return
- Array.Copy(BitConverter.GetBytes(currentStepForMCU * 360 / 10000000.0), 0, FinalResponseContainer, 3, 8);
- Array.Copy(BitConverter.GetBytes(0.0), 0, FinalResponseContainer, 11, 8);
-
- FinalResponseContainer[2] = 0x1;
- break;
- }
-
- default:
- {
- throw new ArgumentException("Invalid PLCCommandAndQueryTypeEnum value seen while expecting a response: " + CommandQueryTypeEnum.ToString());
- }
- }
- }
- else if (ExpectedResponseStatusEnum == PLCCommandResponseExpectationEnum.MINOR_RESPONSE)
- {
- FinalResponseContainer = new byte[]
- {
- 0x3, 0x0, 0x0
- };
-
- switch (CommandQueryTypeEnum)
- {
- case PLCCommandAndQueryTypeEnum.SET_CONFIGURATION:
- {
- // Copy over data we care about, which for now is only the azimuth
- // We skip over the data concerning the elevation, hence the gap in element access for query
- ushort[] DataToWrite =
- {
- (ushort)((256 * query[3]) + query[4]),
- (ushort)((256 * query[5]) + query[6]),
- (ushort)((256 * query[7]) + query[8]),
- (ushort)((256 * query[9]) + query[10]),
- (ushort)((256 * query[15]) + query[16]),
- 0,
- 0,
- 0,
- 0,
- 0
- };
-
- MCUModbusMaster.WriteMultipleRegisters(MCUConstants.ACTUAL_MCU_WRITE_REGISTER_START_ADDRESS, DataToWrite);
-
- PrintReadInputRegsiterContents("After setting configuration");
- if (SendResetErrorsCommand())
- {
- Console.WriteLine("[ProductionPLCDriver] Successfully sent reset command.");
- PrintReadInputRegsiterContents("After sending reset command");
- FinalResponseContainer[2] = 0x1;
- }
- else
- {
- // Send an error code
- Console.WriteLine("[ProductionPLCDriver] ERROR sending reset command.");
- FinalResponseContainer[2] = 0x2;
- }
-
- break;
- }
-
- case PLCCommandAndQueryTypeEnum.CONTROLLED_STOP:
- {
- // There was already a helper function to execute a controlled stop, so just call that
- // Send an error code if there's a failure for some reason
- FinalResponseContainer[2] = (byte)(SendEmptyMoveCommand() ? 0x1 : 0x2);
- break;
- }
-
- case PLCCommandAndQueryTypeEnum.IMMEDIATE_STOP:
- {
- // There was already a helper function to execute a controlled stop, so just call that
- // Send an error code if there's a failure for some reason
- FinalResponseContainer[2] = (byte)(SendImmediateStopCommand() ? 0x1 : 0x2);
- break;
- }
-
- case PLCCommandAndQueryTypeEnum.SET_OBJECTIVE_AZEL_POSITION:
- {
- PrintReadInputRegsiterContents("Before setting objective position");
-
- // Copy over data we care about, so skip over the data concerning the elevation
- double discrepancyMultiplier = 1.0;
- double objectiveAZDouble = BitConverter.ToDouble(query, 3);
- int stepChange = (int)(discrepancyMultiplier * Math.Pow(2, MCUConstants.ACTUAL_MCU_AZIMUTH_ENCODER_BIT_RESOLUTION) * objectiveAZDouble / 360);
- ushort stepChangeUShortMSW = (ushort)((stepChange >> 16) & 0xFFFF);
- ushort stepChangeUShortLSW = (ushort)(stepChange & 0xFFFF);
-
- int programmedPeakSpeed = BitConverter.ToInt32(query, 7);
- ushort programmedPeakSpeedUShortMSW = (ushort)((programmedPeakSpeed >> 16) & 0xFFFF);
- ushort programmedPeakSpeedUShortLSW = (ushort)(programmedPeakSpeed & 0xFFFF);
-
- ushort[] DataToWrite =
- {
- 0x2, // Denotes a relative move in command mode
- 0x3, // Denotes a Trapezoidal S-Curve profile
- stepChangeUShortMSW,
- stepChangeUShortLSW,
- programmedPeakSpeedUShortMSW,
- programmedPeakSpeedUShortLSW,
- MCUConstants.ACTUAL_MCU_MOVE_ACCELERATION_WITH_GEARING,
- MCUConstants.ACTUAL_MCU_MOVE_ACCELERATION_WITH_GEARING,
- 0,
- 0
- };
-
- MCUModbusMaster.WriteMultipleRegisters(MCUConstants.ACTUAL_MCU_WRITE_REGISTER_START_ADDRESS, DataToWrite);
-
- PrintReadInputRegsiterContents("After setting objective position");
-
- FinalResponseContainer[2] = 0x1;
- break;
- }
-
- case PLCCommandAndQueryTypeEnum.START_JOG_MOVEMENT:
- {
- PrintReadInputRegsiterContents("Before starting jog command");
-
- // Make sure the command is intended for the azimuth
- if (query[3] != 0x1)
- {
- throw new ArgumentException("Unsupported value for axis specified in jog command for ProductionPLCDriver: " + query[3].ToString());
- }
-
- ushort programmedPeakSpeedUShortMSW = (ushort)((256 * query[4]) + query[5]);
- ushort programmedPeakSpeedUShortLSW = (ushort)((256 * query[6]) + query[7]);
-
- ushort commandCode;
- switch (query[8])
- {
- case 0x1:
- {
- commandCode = 0x80;
- break;
- }
-
- case 0x2:
- {
- commandCode = 0x100;
- break;
- }
-
- default:
- {
- throw new ArgumentException("Unsupported value for motor movement direction in jog command for ProductionPLCDriver: " + query[8].ToString());
- }
- }
-
- ushort[] DataToWrite =
- {
- commandCode, // Denotes a jog move, either CW or CCW, in command mode
- 0x3, // Denotes a Trapezoidal S-Curve profile
- 0, // Reserved to 0 for a jog command
- 0, // Reserved to 0 for a jog command
- programmedPeakSpeedUShortMSW,
- programmedPeakSpeedUShortLSW,
- MCUConstants.ACTUAL_MCU_MOVE_ACCELERATION_WITH_GEARING,
- MCUConstants.ACTUAL_MCU_MOVE_ACCELERATION_WITH_GEARING,
- 0,
- 0
- };
-
- MCUModbusMaster.WriteMultipleRegisters(MCUConstants.ACTUAL_MCU_WRITE_REGISTER_START_ADDRESS, DataToWrite);
-
- PrintReadInputRegsiterContents("After starting jog command");
-
- FinalResponseContainer[2] = 0x1;
- break;
- }
-
- case PLCCommandAndQueryTypeEnum.TRANSLATE_AZEL_POSITION:
- {
- PrintReadInputRegsiterContents("Before starting relative move");
-
- // Make sure the command is intended for the azimuth
- if (query[3] != 0x1)
- {
- throw new ArgumentException("Unsupported value for axis specified in move relative command for ProductionPLCDriver: " + query[3].ToString());
- }
-
- ushort programmedPeakSpeedUShortMSW = (ushort)((256 * query[4]) + query[5]);
- ushort programmedPeakSpeedUShortLSW = (ushort)((256 * query[6]) + query[7]);
-
- short programmedPositionUShortMSW = (short)((256 * query[8]) + query[9]);
- short programmedPositionUShortLSW = (short)((256 * query[10]) + query[11]);
-
- ushort[] DataToWrite =
- {
- 0x2, // Denotes a relative move
- 0x3, // Denotes a Trapezoidal S-Curve profile
- (ushort)programmedPositionUShortMSW, // MSW for position
- (ushort)programmedPositionUShortLSW, // LSW for position
- programmedPeakSpeedUShortMSW,
- programmedPeakSpeedUShortLSW,
- MCUConstants.ACTUAL_MCU_MOVE_ACCELERATION_WITH_GEARING,
- MCUConstants.ACTUAL_MCU_MOVE_ACCELERATION_WITH_GEARING,
- 0,
- 0
- };
-
- MCUModbusMaster.WriteMultipleRegisters(MCUConstants.ACTUAL_MCU_WRITE_REGISTER_START_ADDRESS, DataToWrite);
-
- PrintReadInputRegsiterContents("After starting relative move command");
-
- FinalResponseContainer[2] = 0x1;
- break;
- }
-
- default:
- {
- throw new ArgumentException("Invalid PLCCommandAndQueryTypeEnum value seen while NOT expecting a response: " + CommandQueryTypeEnum.ToString());
- }
- }
- }
- else
- {
- throw new ArgumentException("Invalid PLCCommandResponseExpectationEnum value seen while processing client request in ProductionPLCDriver: " + ExpectedResponseStatusEnum.ToString());
- }
-
- return AttemptToWriteDataToServer(ActiveClientStream, FinalResponseContainer);
- }
-
- private bool AttemptToWriteDataToServer(NetworkStream activeClientStream, byte[] finalResponseContainer)
- {
- throw new NotImplementedException();
- }
-
- ///
- ///
- ///
- protected override void HandleClientManagementThread()
- {
- //return;
- TcpClient AcceptedClient = null;
- byte[] StreamBuffer = new byte[256];
- byte[] ClippedData;
-
- while (!KillClientManagementThreadFlag)
- {
- if (PLCTCPListener.Pending())
- {
- AcceptedClient = PLCTCPListener.AcceptTcpClient();
- logger.Info("[AbstractPLCDriver] Connected to new client.");
-
- NetworkStream ClientStream = AcceptedClient.GetStream();
-
- int Fd;
- while ((!KillClientManagementThreadFlag) && (ClientStream != null))
- {
- if ((!ClientStream.CanRead) || (!ClientStream.DataAvailable))
- {
- continue;
- }
-
- Fd = ClientStream.Read(StreamBuffer, 0, StreamBuffer.Length);
-
- if (Fd == 0)
- {
- continue;
- }
-
- try
- {
- ClippedData = new byte[Fd];
- Array.Copy(StreamBuffer, ClippedData, ClippedData.Length);
-
- if (!ProcessRequest(ClientStream, ClippedData))
- {
- logger.Info("[AbstractPLCDriver] FAILED to write server.");
- }
- else
- {
- //logger.Info("[AbstractPLCDriver] Successfully wrote to server: [{0}]", string.Join(", ", ClippedData));
- //logger.Info("[AbstractPLCDriver] Successfully wrote to server!");
- }
- }
- catch (Exception e)
- {
- if ((e is ArgumentNullException)
- || (e is RankException)
- || (e is ArrayTypeMismatchException)
- || (e is InvalidCastException)
- || (e is ArgumentOutOfRangeException)
- || (e is ArgumentException))
- {
- logger.Info("[AbstractPLCDriver] ERROR: copying buffer array into clipped array {" + Fd + "}, skipping... [" + e.ToString());
- continue;
- }
- else
- {// Unexpected exception
- throw e;
- }
- }
- }
-
- ClientStream.Dispose();
- AcceptedClient.Dispose();
- }
- }
- }
-
- public override bool StartAsyncAcceptingClients()
- {
- throw new NotImplementedException();
- }
-
- public override bool RequestStopAsyncAcceptingClientsAndJoin()
- {
- throw new NotImplementedException();
- }
-
- public override void Bring_down()
- {
- throw new NotImplementedException();
- }
-
- public override bool Test_Conection()
- {
- throw new NotImplementedException();
- }
-
- public override Orientation read_Position()
- {
- throw new NotImplementedException();
- }
-
- public override bool Cancle_move()
- {
- throw new NotImplementedException();
- }
-
- public override bool Shutdown_PLC_MCU()
- {
- throw new NotImplementedException();
- }
-
- public override bool Calibrate()
- {
- throw new NotImplementedException();
- }
-
- public override bool Configure_MCU(int startSpeedAzimuth, int startSpeedElevation, int homeTimeoutAzimuth, int homeTimeoutElevation)
- {
- throw new NotImplementedException();
- }
-
- public override bool Controled_stop(RadioTelescopeAxisEnum axis, bool both)
- {
- throw new NotImplementedException();
- }
-
- public override bool Immediade_stop()
- {
- throw new NotImplementedException();
- }
-
- public override bool relative_move(int programmedPeakSpeedAZInt, ushort ACCELERATION, int positionTranslationAZ, int positionTranslationEL)
- {
- throw new NotImplementedException();
- }
-
- public override bool Move_to_orientation(Orientation target_orientation, Orientation current_orientation)
- {
- throw new NotImplementedException();
- }
-
- public override bool Start_jog(RadioTelescopeAxisEnum axis, int speed, bool clockwise)
- {
- throw new NotImplementedException();
- }
-
- public override bool Get_interlock_status()
- {
- throw new NotImplementedException();
- }
-
- public override bool[] Get_Limit_switches()
- {
- throw new NotImplementedException();
- }
-
- public override bool[] GET_MCU_Status()
- {
- throw new NotImplementedException();
- }
-
- protected override bool TestIfComponentIsAlive() {
- throw new NotImplementedException();
- }
-
- }
-}
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/PLCCommunication/PLCDrivers/ProductionPLCDriver.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/PLCCommunication/PLCDrivers/ProductionPLCDriver.cs
index 6bb2a82e..bd2c6976 100644
--- a/ControlRoomApplication/ControlRoomApplication/Controllers/PLCCommunication/PLCDrivers/ProductionPLCDriver.cs
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/PLCCommunication/PLCDrivers/ProductionPLCDriver.cs
@@ -9,6 +9,18 @@
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
+using System.Diagnostics;
+using ControlRoomApplication.Entities.Configuration;
+using ControlRoomApplication.Controllers.Communications;
+using ControlRoomApplication.Controllers.PLCCommunication;
+using ControlRoomApplication.Util;
+using System.Collections.Generic;
+using static ControlRoomApplication.Constants.MCUConstants;
+using ControlRoomApplication.Database;
+using System.Timers;
+using ControlRoomApplication.Controllers.PLCCommunication.PLCDrivers.MCUManager;
+using ControlRoomApplication.Controllers.PLCCommunication.PLCDrivers.MCUManager.Enumerations;
+using ControlRoomApplication.Controllers.Sensors;
namespace ControlRoomApplication.Controllers
{
@@ -20,35 +32,18 @@ public class ProductionPLCDriver : AbstractPLCDriver
private static readonly log4net.ILog logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
private TcpListener PLCTCPListener;
- private TcpClient MCUTCPClient;
private ModbusSlave PLC_Modbusserver;
- private ModbusIpMaster MCUModbusMaster;
- private SemaphoreSlim comand_acknoledged = new SemaphoreSlim(0, 1);
- private long PLC_last_contact;
-
- private static readonly ushort[] MESSAGE_CONTENTS_IMMEDIATE_STOP = new ushort[] {
- 0x0010, 0x0003, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0010, 0x0003, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
- };
-
- private static readonly ushort[] MESSAGE_CONTENTS_HOLD_MOVE = new ushort[] {
- 0x0004, 0x0003, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0004, 0x0003, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
- };
-
- private static readonly ushort[] MESSAGE_CONTENTS_CLEAR_MOVE = new ushort[] {
- 0x0000, 0x0003, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0003, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
- };
-
- private static readonly ushort[] MESSAGE_CONTENTS_RESET_ERRORS = new ushort[] {
- 0x0800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
- };
-
- private bool keep_modbus_server_alive=true;
- private bool is_test= false;
- public bool set_is_test(bool val) { is_test = val;return is_test; }//set this ONLY if using test driver, removes timouts and delays
+ private long PLC_last_contact = 0;
+ private bool keep_modbus_server_alive = true;
+ private bool is_test = false;
+ private MCUManager MCU;
+ private RadioTelescopeTypeEnum telescopeType = RadioTelescopeTypeEnum.NONE;
+ ///
+ /// set this ONLY if using test driver, removes timouts and delays
+ ///
+ ///
+ ///
+ public bool set_is_test(bool val) { is_test = val; return is_test; }
///
/// starts a modbus server to comunicate with the PLC on PLC_port and local_ip
/// then sets up a modbus client to comunicate with the MCU located at MCU_ip, MCU_port (192.168.0.50 , 502) for actual hardware
@@ -57,20 +52,22 @@ public class ProductionPLCDriver : AbstractPLCDriver
///
///
///
- public ProductionPLCDriver(string local_ip, string MCU_ip, int MCU_port, int PLC_port) : base(local_ip, MCU_ip, MCU_port, PLC_port)
+ public ProductionPLCDriver(string local_ip, string MCU_ip, int MCU_port, int PLC_port) : base(local_ip, MCU_ip, MCU_port, PLC_port)
{
- MCUTCPClient = new TcpClient(MCU_ip, MCU_port);
- MCUModbusMaster = ModbusIpMaster.CreateIp(MCUTCPClient);
- try
- {
+ limitSwitchData = new Simulators.Hardware.LimitSwitchData();
+ homeSensorData = new Simulators.Hardware.HomeSensorData();
+ pLCEvents = new PLCEvents();
+ MCU = new MCUManager( MCU_ip , MCU_port );
+
+ try {
PLCTCPListener = new TcpListener(new IPEndPoint(IPAddress.Parse(local_ip), PLC_port));
- ClientManagmentThread = new Thread(new ThreadStart(HandleClientManagementThread));
+ ClientManagmentThread = new Thread( new ThreadStart( HandleClientManagementThread ) ) { Name = "PLC server Thread"};
}
catch (Exception e)
{
if ((e is ArgumentNullException) || (e is ArgumentOutOfRangeException))
{
- logger.Info("[AbstractPLCDriver] ERROR: failure creating PLC TCP server or management thread: " + e.ToString());
+ logger.Info(Utilities.GetTimeStamp() + ": [AbstractPLCDriver] ERROR: failure creating PLC TCP server or management thread: " + e.ToString());
return;
}
else { throw e; }// Unexpected exception
@@ -83,68 +80,187 @@ public ProductionPLCDriver(string local_ip, string MCU_ip, int MCU_port, int PL
{
if ((e is SocketException) || (e is ArgumentOutOfRangeException) || (e is InvalidOperationException))
{
- logger.Info("[AbstractPLCDriver] ERROR: failure starting PLC TCP server: " + e.ToString());
+ logger.Info(Utilities.GetTimeStamp() + ": [AbstractPLCDriver] ERROR: failure starting PLC TCP server: " + e.ToString());
return;
}
}
-
}
-
+ public override MovementPriority CurrentMovementPriority { get; set; }
///
/// runs the modbus server to interface with the plc
///
- protected override void HandleClientManagementThread() {
+ public override void HandleClientManagementThread() {
byte slaveId = 1;
// create and start the TCP slave
- PLC_Modbusserver = ModbusTcpSlave.CreateTcp( slaveId , PLCTCPListener );
+ PLC_Modbusserver = ModbusTcpSlave.CreateTcp(slaveId, PLCTCPListener);
//coils, inputs, holdingRegisters, inputRegisters
- PLC_Modbusserver.DataStore = DataStoreFactory.CreateDefaultDataStore( 0 , 0 , 256 , 0 );
+ PLC_Modbusserver.DataStore = DataStoreFactory.CreateDefaultDataStore(0, 0, 256, 0);
// PLC_Modbusserver.DataStore.SyncRoot.ToString();
- PLC_Modbusserver.ModbusSlaveRequestReceived += new EventHandler( Server_Read_handler );
- PLC_Modbusserver.DataStore.DataStoreWrittenTo += new EventHandler( Server_Written_to_handler );
+ PLC_Modbusserver.ModbusSlaveRequestReceived += new EventHandler(Server_Read_handler);
+ PLC_Modbusserver.DataStore.DataStoreWrittenTo += new EventHandler(Server_Written_to_handler);
PLC_Modbusserver.Listen();
//PLC_Modbusserver.ListenAsync().GetAwaiter().GetResult();
// prevent the main thread from exiting
- while(keep_modbus_server_alive) {
- Thread.Sleep( 100 );
+ Task.Delay(2000).Wait();
+
+ PLCEvents.setDefaultLimitHandler( DefaultLimitSwitchHandle );
+
+ while (keep_modbus_server_alive) {
+ Thread.Sleep(1000);
+ PLC_Modbusserver.DataStore.HoldingRegisters[(int)PLC_modbus_server_register_mapping.CTRL_HEART_BEAT]++;
+ }
+ }
+
+ private async void DefaultLimitSwitchHandle( object sender , limitEventArgs e ) {
+ if(e.Value) {
+ switch(e.ChangedValue) {
+ case PLC_modbus_server_register_mapping.AZ_0_LIMIT :
+ {
+ if (!Overrides.overrideAzimuthProx0)
+ {
+ CurrentMovementPriority = MovementPriority.Critical;
+ MCU.SendSingleAxisJog(RadioTelescopeAxisEnum.AZIMUTH, RadioTelescopeDirectionEnum.ClockwiseOrNegative, 0.25);
+ }
+ break;
+ }
+ case PLC_modbus_server_register_mapping.AZ_375_LIMIT:
+ {
+ if (!Overrides.overrideAzimuthProx375)
+ {
+ CurrentMovementPriority = MovementPriority.Critical;
+ MCU.SendSingleAxisJog(RadioTelescopeAxisEnum.AZIMUTH, RadioTelescopeDirectionEnum.CounterclockwiseOrPositive, 0.25);
+ }
+ break;
+ }
+ case PLC_modbus_server_register_mapping.EL_10_LIMIT:
+ {
+ if (!Overrides.overrideElevatProx0)
+ {
+ CurrentMovementPriority = MovementPriority.Critical;
+ MCU.SendSingleAxisJog(RadioTelescopeAxisEnum.ELEVATION, RadioTelescopeDirectionEnum.CounterclockwiseOrPositive, 0.25);
+ }
+ break;
+ }
+ case PLC_modbus_server_register_mapping.EL_90_LIMIT:
+ {
+ if (!Overrides.overrideElevatProx90)
+ {
+ CurrentMovementPriority = MovementPriority.Critical;
+ MCU.SendSingleAxisJog(RadioTelescopeAxisEnum.ELEVATION, RadioTelescopeDirectionEnum.ClockwiseOrNegative, 0.25);
+ }
+ break;
+ }
+ }
+
+ }
+ if(!e.Value) {
+ switch(e.ChangedValue) {
+ case PLC_modbus_server_register_mapping.AZ_0_LIMIT:
+ {
+ if (!Overrides.overrideAzimuthProx0)
+ {
+ MCU.StopSingleAxisJog(RadioTelescopeAxisEnum.AZIMUTH);
+ CurrentMovementPriority = MovementPriority.None;
+ }
+ break;
+ }
+ case PLC_modbus_server_register_mapping.AZ_375_LIMIT:
+ {
+ if (!Overrides.overrideAzimuthProx375)
+ {
+ MCU.StopSingleAxisJog(RadioTelescopeAxisEnum.AZIMUTH);
+ CurrentMovementPriority = MovementPriority.None;
+ }
+ break;
+ }
+ case PLC_modbus_server_register_mapping.EL_10_LIMIT:
+ {
+ if (!Overrides.overrideElevatProx0)
+ {
+ MCU.StopSingleAxisJog(RadioTelescopeAxisEnum.ELEVATION);
+ CurrentMovementPriority = MovementPriority.None;
+ }
+ break;
+ }
+ case PLC_modbus_server_register_mapping.EL_90_LIMIT:
+ {
+ if (!Overrides.overrideElevatProx90)
+ {
+ MCU.StopSingleAxisJog(RadioTelescopeAxisEnum.ELEVATION);
+ CurrentMovementPriority = MovementPriority.None;
+ }
+ break;
+ }
+ }
}
}
+
public override bool StartAsyncAcceptingClients() {
+ MCU.StartAsyncAcceptingClients();
keep_modbus_server_alive = true;
try {
ClientManagmentThread.Start();
- } catch(Exception e) {
- if((e is ThreadStateException) || (e is OutOfMemoryException)) {
+ } catch (Exception e) {
+ if ((e is ThreadStateException) || (e is OutOfMemoryException)) {
+ logger.Error(Utilities.GetTimeStamp() + ": failed to start prodi=uction plc and mcu threads err:____ {0}", e);
return false;
} else { throw e; }// Unexpected exception
}
return true;
}
+ ///
+ /// Waits for the PLC to contact the control room
+ ///
+ ///
+ /// the PLC is constantly trying to send data to the controll room if the control room is not present it will retry again until it sucessfully connects
+ /// this method will return a task that completes when that first contact occurs or when it times out
+ ///
+ ///
+ ///
+ public async Task WaitForPLCConnection(int timeoutS) {
+ var timout = new CancellationTokenSource( timeoutS*1000 );
+ bool PLC_alive = false;
+ while(!timout.Token.IsCancellationRequested && !PLC_alive) {
+ PLC_alive = (DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() - PLC_last_contact) < 3000;
+ Task.Delay( 50 ).Wait();
+ if(PLC_alive) {
+ timout.Dispose();
+ logger.Info(Utilities.GetTimeStamp() + ": sucsefully conected to the PLC");
+ return;
+ }
+ }
+ timout.Dispose();
+ return;
+ }
public override bool RequestStopAsyncAcceptingClientsAndJoin() {
+ MCU.RequestStopAsyncAcceptingClientsAndJoin();
keep_modbus_server_alive = false;
- try {
+ try
+ {
+ PLC_Modbusserver.Dispose();
+ PLCTCPListener.Stop();
ClientManagmentThread.Join();
- } catch(Exception e) {
- if((e is ThreadStateException) || (e is ThreadStartException)) {
- Console.WriteLine( e );
+ } catch (Exception e) {
+ if ((e is ThreadStateException) || (e is ThreadStartException)) {
+ logger.Error(e);
return false;
} else { throw e; }// Unexpected exception
}
return true;
}
-
public override void Bring_down() {
RequestStopAsyncAcceptingClientsAndJoin();
+
}
///
@@ -152,128 +268,175 @@ public override void Bring_down() {
///
///
///
- private void Server_Read_handler(object sender, ModbusSlaveRequestEventArgs e)
- {
+ private void Server_Read_handler(object sender, ModbusSlaveRequestEventArgs e) {
+ if (is_test) {
+ logger.Info(Utilities.GetTimeStamp() + ": PLC Red data from the the control room");
+ }
PLC_last_contact = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
- // Console.WriteLine(e.Message);
return;
- Regex rx = new Regex(@"\b(?:Read )([0-9]+)(?:.+)(?:address )([0-9]+)\b", RegexOptions.Compiled | RegexOptions.IgnoreCase);
- MatchCollection matches = rx.Matches(e.Message.ToString());
- foreach (Match match in matches)
- {
- GroupCollection groups = match.Groups;
- Console.WriteLine("'{0}' repeated at positions {1} and {2}", groups["word"].Value, groups[0].Index, groups[1].Index);
- }
- // PLC_Modbusserver.DataStore.HoldingRegisters[e.] += 1;
- //throw new NotImplementedException();
}
+
///
/// fires whenever the data on the modbus server changes
///
///
///
- private void Server_Written_to_handler( object sender , DataStoreEventArgs e ) {
+ private void Server_Written_to_handler(object sender, DataStoreEventArgs e) {
//e.Data.B //array representing data
-
- switch(e.StartAddress) {//
- case (ushort)PLC_modbus_server_register_mapping.CMD_ACK: {
- // Console.WriteLine(" data {0} written to 22",PLC_Modbusserver.DataStore.HoldingRegisters[e.StartAddress]);
- try {
- //comand_acknoledged.Release();
- } catch(Exception err) {
- Console.WriteLine( err );
+ if (is_test) {
+ logger.Info(Utilities.GetTimeStamp() + ": recived message from PLC");
+ }
+ PLC_last_contact = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
+ switch (e.StartAddress) {
+ case (ushort)PLC_modbus_server_register_mapping.AZ_0_LIMIT: {
+ bool previous = limitSwitchData.Azimuth_CCW_Limit;
+ limitSwitchData.Azimuth_CCW_Limit = !Int_to_bool( PLC_Modbusserver.DataStore.HoldingRegisters[(int)PLC_modbus_server_register_mapping.AZ_0_LIMIT] );
+ if(previous != limitSwitchData.Azimuth_CCW_Limit) {
+ pLCEvents.PLCLimitChanged( limitSwitchData , PLC_modbus_server_register_mapping.AZ_0_LIMIT , limitSwitchData.Azimuth_CCW_Limit );
}
break;
-
}
- case (ushort)PLC_modbus_server_register_mapping.AZ_LEFT_LIMIT: {
-
+ case (ushort)PLC_modbus_server_register_mapping.AZ_0_HOME: {
+ bool previous = homeSensorData.Azimuth_Home_One;
+ homeSensorData.Azimuth_Home_One = Int_to_bool( PLC_Modbusserver.DataStore.HoldingRegisters[(int)PLC_modbus_server_register_mapping.AZ_0_HOME] );
break;
}
- case (ushort)PLC_modbus_server_register_mapping.AZ_LEFT_WARNING: {
-
+ case (ushort)PLC_modbus_server_register_mapping.AZ_0_SECONDARY: {
+ bool previous = homeSensorData.Azimuth_Home_Two;
+ homeSensorData.Azimuth_Home_Two = Int_to_bool( PLC_Modbusserver.DataStore.HoldingRegisters[(int)PLC_modbus_server_register_mapping.AZ_0_SECONDARY] );
break;
}
- case (ushort)PLC_modbus_server_register_mapping.AZ_RIGHT_WARNING: {
-
+ case (ushort)PLC_modbus_server_register_mapping.AZ_375_LIMIT: {
+ bool previous = limitSwitchData.Azimuth_CW_Limit;
+ limitSwitchData.Azimuth_CW_Limit = !Int_to_bool( PLC_Modbusserver.DataStore.HoldingRegisters[(int)PLC_modbus_server_register_mapping.AZ_375_LIMIT] );
+ if(previous != limitSwitchData.Azimuth_CW_Limit) {
+ pLCEvents.PLCLimitChanged( limitSwitchData , PLC_modbus_server_register_mapping.AZ_375_LIMIT , limitSwitchData.Azimuth_CW_Limit );
+ }
break;
}
- case (ushort)PLC_modbus_server_register_mapping.AZ_RIGHT_LIMIT: {
-
+ case (ushort)PLC_modbus_server_register_mapping.EL_10_LIMIT: {
+ bool previous = limitSwitchData.Elevation_Lower_Limit;
+ limitSwitchData.Elevation_Lower_Limit = !Int_to_bool( PLC_Modbusserver.DataStore.HoldingRegisters[(int)PLC_modbus_server_register_mapping.EL_10_LIMIT]);
+ if(previous != limitSwitchData.Elevation_Lower_Limit) {
+ pLCEvents.PLCLimitChanged( limitSwitchData , PLC_modbus_server_register_mapping.EL_10_LIMIT , limitSwitchData.Elevation_Lower_Limit );
+ if (limitSwitchData.Elevation_Lower_Limit)
+ {
+ logger.Info(Utilities.GetTimeStamp() + ": Elevation Lower Limit Switch Hit");
+
+ pushNotification.sendToAllAdmins("LIMIT SWITCH", "Elevation lower limit switch hit");
+ EmailNotifications.sendToAllAdmins("LIMIT SWITCH", "Elevation lower limit switch hit");
+ }
+ }
break;
}
- case (ushort)PLC_modbus_server_register_mapping.EL_BOTTOM_LIMIT: {
-
+ case (ushort)PLC_modbus_server_register_mapping.EL_0_HOME: {
+ bool previous = homeSensorData.Elevation_Home;
+ homeSensorData.Elevation_Home = Int_to_bool( PLC_Modbusserver.DataStore.HoldingRegisters[(int)PLC_modbus_server_register_mapping.EL_0_HOME] );
break;
}
- case (ushort)PLC_modbus_server_register_mapping.EL_BOTTOM_WARNING: {
-
+ case (ushort)PLC_modbus_server_register_mapping.EL_90_LIMIT: {
+ bool previous = limitSwitchData.Elevation_Upper_Limit;
+ limitSwitchData.Elevation_Upper_Limit = !Int_to_bool( PLC_Modbusserver.DataStore.HoldingRegisters[(int)PLC_modbus_server_register_mapping.EL_90_LIMIT] );
+ if(previous != limitSwitchData.Elevation_Upper_Limit) {
+ pLCEvents.PLCLimitChanged( limitSwitchData , PLC_modbus_server_register_mapping.EL_90_LIMIT , limitSwitchData.Elevation_Upper_Limit );
+ if (limitSwitchData.Elevation_Upper_Limit)
+ {
+ logger.Info(Utilities.GetTimeStamp() + ": Elevation Upper Limit Switch Hit");
+
+ pushNotification.sendToAllAdmins("LIMIT SWITCH", "Elevation upper limit switch hit");
+ EmailNotifications.sendToAllAdmins("LIMIT SWITCH", "Elevation upper limit switch hit");
+ }
+ }
break;
}
- case (ushort)PLC_modbus_server_register_mapping.EL_TOP_WARNING: {
-
+ case (ushort)PLC_modbus_server_register_mapping.Gate_Safety_INTERLOCK: {
+ bool previous = plcInput.Gate_Sensor;
+ plcInput.Gate_Sensor = !Int_to_bool( PLC_Modbusserver.DataStore.HoldingRegisters[(int)PLC_modbus_server_register_mapping.Gate_Safety_INTERLOCK] );
+ if(previous != plcInput.Gate_Sensor) {
+ if (plcInput.Gate_Sensor)
+ {
+ logger.Info(Utilities.GetTimeStamp() + ": gate opened");
+
+ pushNotification.sendToAllAdmins("GATE ACTIVITY", "Gate has been opened.");
+ EmailNotifications.sendToAllAdmins("GATE ACTIVITY", "Gate has been opened.");
+ }
+ else
+ {
+ logger.Info(Utilities.GetTimeStamp() + ": gate closed");
+
+ pushNotification.sendToAllAdmins("GATE ACTIVITY", "Gate has been closed.");
+ EmailNotifications.sendToAllAdmins("GATE ACTIVITY", "Gate has been closed.");
+ }
+ }
break;
}
- case (ushort)PLC_modbus_server_register_mapping.EL_TOP_LIMIT: {
-
+ case (ushort)PLC_modbus_server_register_mapping.E_STOP: {
+ bool previous = plcInput.Estop;
+ plcInput.Estop = !Int_to_bool( PLC_Modbusserver.DataStore.HoldingRegisters[(int)PLC_modbus_server_register_mapping.E_STOP] );
+ if(previous != plcInput.Estop) {
+ if (plcInput.Estop)
+ {
+ logger.Info(Utilities.GetTimeStamp() + ": Estop Hit");
+ CurrentMovementPriority = MovementPriority.Critical;
+
+ pushNotification.sendToAllAdmins("E-STOP ACTIVITY", "E-stop has been hit.");
+ EmailNotifications.sendToAllAdmins("E-STOP ACTIVITY", "E-stop has been hit.");
+ }
+ else
+ {
+ logger.Info(Utilities.GetTimeStamp() + ": Estop released");
+ CurrentMovementPriority = MovementPriority.None;
+
+ pushNotification.sendToAllAdmins("E-STOP ACTIVITY", "E-stop has been released.");
+ EmailNotifications.sendToAllAdmins("E-STOP ACTIVITY", "E-stop has been released.");
+ }
+ }
+ break;
+ }
+ case (ushort)PLC_modbus_server_register_mapping.EL_SLIP_CAPTURE: {
+ bool previous = plcInput.EL_Slip_CAPTURE;
+ plcInput.EL_Slip_CAPTURE = Int_to_bool( PLC_Modbusserver.DataStore.HoldingRegisters[(int)PLC_modbus_server_register_mapping.EL_SLIP_CAPTURE] );
break;
}
}
}
- private void set_Local_registers( ushort[] data , ushort starting_adress ) {
- Console.WriteLine( "{0} dsv {1} " , data.Length , starting_adress );
- for(int i = 1; i < (data.Length - 1); i++) {
+ private void set_Local_registers(ushort[] data, ushort starting_adress) {
+ logger.Info(data.Length + " dsv " + starting_adress);
+ for (int i = 1; i < (data.Length - 1); i++) {
PLC_Modbusserver.DataStore.HoldingRegisters[i + starting_adress] = data[i];
- Console.Write( " {0}," , PLC_Modbusserver.DataStore.HoldingRegisters[i + starting_adress] );
+ logger.Info( " " + PLC_Modbusserver.DataStore.HoldingRegisters[i + starting_adress] + ",");
}
}
///
- ///
+ /// Sets a register value on the PLC that corresponds to the given address.
///
- ///
- ///
- public void setregvalue( ushort adr , ushort value ) {
+ /// The address of the value you want to set.
+ /// The value you want to set the register to.
+ public override void setregvalue(ushort adr, ushort value) {
PLC_Modbusserver.DataStore.HoldingRegisters[adr] = value;
}
///
- /// see ControlRoomApplication.Entities.PLC_modbus_server_register_mapping
- /// for register maping
+ /// Retrieves a register value from the PLC that corresponds to the given address.
///
- ///
- ///
- public ushort readregval( ushort adr ) {
+ ///
+ /// See ControlRoomApplication.Entities.PLC_modbus_server_register_mapping for register mapping.
+ ///
+ /// Address of the register.
+ public override ushort getregvalue(ushort adr)
+ {
return PLC_Modbusserver.DataStore.HoldingRegisters[adr];
}
-
-
public override bool Get_interlock_status() {
- return Int_to_bool( PLC_Modbusserver.DataStore.HoldingRegisters[(ushort)PLC_modbus_server_register_mapping.Safty_INTERLOCK] );
- }
-
-
- public override bool[] Get_Limit_switches() {
- return new bool[] {
- Int_to_bool(PLC_Modbusserver.DataStore.HoldingRegisters[(ushort)PLC_modbus_server_register_mapping.AZ_LEFT_LIMIT]),
- Int_to_bool(PLC_Modbusserver.DataStore.HoldingRegisters[(ushort)PLC_modbus_server_register_mapping.AZ_LEFT_WARNING]),
- Int_to_bool(PLC_Modbusserver.DataStore.HoldingRegisters[(ushort)PLC_modbus_server_register_mapping.AZ_RIGHT_WARNING]),
- Int_to_bool(PLC_Modbusserver.DataStore.HoldingRegisters[(ushort)PLC_modbus_server_register_mapping.AZ_RIGHT_LIMIT]),
-
- Int_to_bool(PLC_Modbusserver.DataStore.HoldingRegisters[(ushort)PLC_modbus_server_register_mapping.EL_BOTTOM_LIMIT]),
- Int_to_bool(PLC_Modbusserver.DataStore.HoldingRegisters[(ushort)PLC_modbus_server_register_mapping.EL_BOTTOM_WARNING]),
- Int_to_bool(PLC_Modbusserver.DataStore.HoldingRegisters[(ushort)PLC_modbus_server_register_mapping.EL_TOP_WARNING]),
- Int_to_bool(PLC_Modbusserver.DataStore.HoldingRegisters[(ushort)PLC_modbus_server_register_mapping.EL_TOP_LIMIT])
- };
+ return plcInput.Gate_Sensor;
}
-
- private bool Int_to_bool( int val ) {
- Console.WriteLine( val );
- if(val == 0) {
+ private bool Int_to_bool(int val) {
+ if (val == 0) {
return false;
} else { return true; }
}
@@ -282,229 +445,310 @@ private bool Int_to_bool( int val ) {
//above PLC modbus server ___below MCU comands
-
-
-
-
- public override bool Test_Conection()//TODO: make moar godder
- {
- return true;
+ public override bool Test_Connection() {
+ return TestIfComponentIsAlive();
}
- public override bool Calibrate() {//im uncertin what tasks we want this method to preform
- if(is_test) { return true; }
- throw new NotImplementedException();
+ ///
+ /// send basic configuration to MCU
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public override bool Configure_MCU(double startSpeedRPMAzimuth, double startSpeedRPMElevation, int homeTimeoutSecondsAzimuth, int homeTimeoutSecondsElevation) {
+ return MCU.Configure_MCU(
+ new MCUConfigurationAxys() { StartSpeed = startSpeedRPMAzimuth, HomeTimeoutSec = homeTimeoutSecondsAzimuth },
+ new MCUConfigurationAxys() { StartSpeed = startSpeedRPMElevation, HomeTimeoutSec = homeTimeoutSecondsElevation,UseCapture =true,CaptureActive_High =true }
+ );
}
- public override bool Configure_MCU( int startSpeedDPSAzimuth , int startSpeedDPSElevation , int homeTimeoutSecondsAzimuth , int homeTimeoutSecondsElevation ) {
- int gearedSpeedAZ = ConversionHelper.DPSToSPS( startSpeedDPSAzimuth , MotorConstants.GEARING_RATIO_AZIMUTH );
- int gearedSpeedEL = ConversionHelper.DPSToSPS( startSpeedDPSElevation , MotorConstants.GEARING_RATIO_ELEVATION );
- if((gearedSpeedAZ < 1) || (gearedSpeedEL < 1) || (homeTimeoutSecondsAzimuth < 0) || (homeTimeoutSecondsElevation < 0)
- || (gearedSpeedAZ > 1000000) || (gearedSpeedEL > 1000000) || (homeTimeoutSecondsAzimuth > 300) || (homeTimeoutSecondsElevation > 300)) {
- return false;
- }
- ushort[] data = { 0x8400, 0x0000, (ushort)(gearedSpeedAZ >> 0x0010), (ushort)(gearedSpeedAZ & 0xFFFF), (ushort)homeTimeoutSecondsAzimuth,
- 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x8400, 0x0000, (ushort)(gearedSpeedEL >> 0x0010), (ushort)(gearedSpeedEL & 0xFFFF), (ushort)homeTimeoutSecondsElevation,
- 0x0, 0x0, 0x0, 0x0, 0x0
- };
- //set_multiple_registers( data, 1);
- MCUModbusMaster.WriteMultipleRegisters( MCUConstants.ACTUAL_MCU_WRITE_REGISTER_START_ADDRESS , data );
- return true;
- }
///
/// this gets the position stored in the MCU which is based of the number of steps the MCU has taken since it was last 0ed out
///
///
- public override Orientation read_Position(){
- ushort[] data = MCUModbusMaster.ReadHoldingRegisters(2, 12);
- // Console.WriteLine("AZ_finni2 {0,10} EL_finni2 {1,10}", (65536 * data[0]) + data[1], (65536 * data[10]) + data[11]);
- Orientation current_orientation = new Orientation(
- ConversionHelper.StepsToDegrees((data[0]<<16) + data[1], MotorConstants.GEARING_RATIO_AZIMUTH),
- ConversionHelper.StepsToDegrees((data[10]<<16) + data[11], MotorConstants.GEARING_RATIO_ELEVATION)
- );
- return current_orientation;
+ public override Orientation GetMotorEncoderPosition() {
+ return MCU.GetMotorEncoderPosition();
}
+
///
/// get an array of boolens representiing the register described on pages 76 -79 of the mcu documentation
+ /// does not suport RadioTelescopeAxisEnum.BOTH
+ /// see for description of each bit
///
- public override bool[] GET_MCU_Status() {
- ushort data = MCUModbusMaster.ReadHoldingRegisters( 0 , 1 )[0];
- bool[] target = new bool[16];
+ public override bool[] GET_MCU_Status( RadioTelescopeAxisEnum axis ) {
+ ushort start = 0;
+ if(axis == RadioTelescopeAxisEnum.ELEVATION) {
+ start = 10;
+ }
+ ushort[] data = MCU.ReadMCURegisters(start , 2);
+ bool[] target = new bool[32];
for(int i = 0; i < 16; i++) {
- target[i] = ((data >> i) & 1) == 1;
+ target[i] = ((data[0] >> i) & 1) == 1;
+ target[i + 16] = ((data[1] >> i) & 1) == 1;
+
}
return target;
-
}
+
///
- /// clears the previos move comand from mthe PLC
+ /// clears the previos move comand from mthe PLC, only works for jog moves
///
///
- public override bool Cancle_move() {
- MCUModbusMaster.WriteMultipleRegisters( MCUConstants.ACTUAL_MCU_WRITE_REGISTER_START_ADDRESS , MESSAGE_CONTENTS_CLEAR_MOVE );
- return true;
+ public override MovementResult Cancel_move() {
+ return MCU.Cancel_move();
}
+ ///
+ /// send a hold move command to the MCu
+ ///
+ ///
+ public override MovementResult ControlledStop( ) {
+ return MCU.ControlledStop();
+ }
- public override bool Controled_stop( RadioTelescopeAxisEnum axis , bool both ) {
- ushort[] data = new ushort[] { 0x4 , 0x3 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
- if(both) {
- MCUModbusMaster.WriteMultipleRegisters( MCUConstants.ACTUAL_MCU_WRITE_REGISTER_START_ADDRESS , MESSAGE_CONTENTS_HOLD_MOVE );
- return true;
- } else if (axis== RadioTelescopeAxisEnum.AZIMUTH) {
- MCUModbusMaster.WriteMultipleRegisters( MCUConstants.ACTUAL_MCU_WRITE_REGISTER_START_ADDRESS , data );
- return true;
- } else if(axis == RadioTelescopeAxisEnum.ELEVATION) {
- MCUModbusMaster.WriteMultipleRegisters( MCUConstants.ACTUAL_MCU_WRITE_REGISTER_START_ADDRESS+10 , data );
- return true;
- }
- return false;
+ public override MovementResult ImmediateStop() {
+ return MCU.ImmediateStop();
}
- public override bool Immediade_stop() {
- MCUModbusMaster.WriteMultipleRegisters( MCUConstants.ACTUAL_MCU_WRITE_REGISTER_START_ADDRESS , MESSAGE_CONTENTS_IMMEDIATE_STOP );
- return true;
+ ///
+ /// move a set number of steps at the specified steps / second *intended for debuging
+ ///
+ ///
+ ///
+ ///
+ /// The target orientation.
+ ///
+ public override MovementResult RelativeMove(int programmedPeakSpeedAZInt, int programmedPeakSpeedELInt, int positionTranslationAZ, int positionTranslationEL, Orientation targetOrientation) {
+ return MCU.MoveAndWaitForCompletion(programmedPeakSpeedAZInt, programmedPeakSpeedELInt, positionTranslationAZ, positionTranslationEL, targetOrientation);
}
- public override bool Shutdown_PLC_MCU()
+ public override MovementResult MoveToOrientation(Orientation target_orientation, Orientation current_orientation)
{
- Orientation stow = new Orientation(0, 0);///////////////////////change this and the value in TestShutdownRadioTelescope
+ int positionTranslationAZ, positionTranslationEL;
- Move_to_orientation(stow, read_Position());
- if (is_test) { return true; }
- throw new NotImplementedException();
+ // Calculates the hard stop calculation by default
+ double azimuthOrientationMovement = target_orientation.Azimuth - current_orientation.Azimuth;
+
+ // If the type is a slip ring, checks to see if it needs to calculate a new route
+ if(telescopeType == RadioTelescopeTypeEnum.SLIP_RING)
+ {
+ if(azimuthOrientationMovement > 180)
+ {
+ azimuthOrientationMovement = (target_orientation.Azimuth - 360) - current_orientation.Azimuth;
+ }
+ else if(azimuthOrientationMovement < -180)
+ {
+ azimuthOrientationMovement = (360 - current_orientation.Azimuth) + target_orientation.Azimuth;
+ }
+ }
+ else if(telescopeType == RadioTelescopeTypeEnum.NONE)
+ {
+ logger.Info(Utilities.GetTimeStamp() + ": ERROR: Invalid Telescope Type!");
+ return MovementResult.ValidationError;
+ }
+
+ positionTranslationAZ = ConversionHelper.DegreesToSteps(azimuthOrientationMovement, MotorConstants.GEARING_RATIO_AZIMUTH);
+ positionTranslationEL = ConversionHelper.DegreesToSteps((target_orientation.Elevation - current_orientation.Elevation), MotorConstants.GEARING_RATIO_ELEVATION);
+
+ int EL_Speed = ConversionHelper.DPSToSPS( ConversionHelper.RPMToDPS( 0.6 ), MotorConstants.GEARING_RATIO_ELEVATION);
+ int AZ_Speed = ConversionHelper.DPSToSPS( ConversionHelper.RPMToDPS( 0.6 ), MotorConstants.GEARING_RATIO_AZIMUTH);
+
+ //(ObjectivePositionStepsAZ - CurrentPositionStepsAZ), (ObjectivePositionStepsEL - CurrentPositionStepsEL)
+ logger.Info(Utilities.GetTimeStamp() + ": degrees target az " + target_orientation.Azimuth + " el " + target_orientation.Elevation);
+ logger.Info(Utilities.GetTimeStamp() + ": degrees curren az " + current_orientation.Azimuth + " el " + current_orientation.Elevation);
+
+ return MCU.MoveAndWaitForCompletion(
+ AZ_Speed, EL_Speed,
+ positionTranslationAZ,
+ positionTranslationEL,
+ target_orientation
+ );
}
+ ///
+ /// speed in RPM
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public override MovementResult StartBothAxesJog(double azSpeed, RadioTelescopeDirectionEnum azDirection, double elSpeed, RadioTelescopeDirectionEnum elDirection) {
+ return MCU.SendBothAxesJog(Math.Abs(azSpeed), azDirection, Math.Abs(elSpeed), elDirection);
+ }
+ ///
+ /// Moves both axes to where the homing sensors are. After this is run, the position offset needs applied to the motors, and then
+ /// the absolute encoders.
+ ///
+ /// True if homing was successful, false if it failed
+ public override MovementResult HomeTelescope() {
+ return MCU.HomeBothAxes(0.25);
+ }
+
+ ///
+ /// Tests if both the PLC and MCU are alive and working.
+ ///
+ /// True if both the MCU and PLC are alive and working.
+ public override bool TestIfComponentIsAlive() {
+ bool PLC_alive, MCU_alive;
+ try {
+ long MCU_last_contact = MCU.getLastContact();
+ PLC_alive = (DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() - PLC_last_contact) < 3000;
+ MCU_alive = (DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() - MCU_last_contact) < 3000;
+ if(is_test) {
+ return true;
+ }
+ return PLC_alive && MCU_alive;
+ } catch { return false; }
+ }
+ public override void setTelescopeType(RadioTelescopeTypeEnum type)
+ {
+ telescopeType = type;
- public override bool relative_move( int programmedPeakSpeedAZInt , ushort ACCELERATION , int positionTranslationAZ , int positionTranslationEL ) {
- return send_relative_move( programmedPeakSpeedAZInt , programmedPeakSpeedAZInt , ACCELERATION , positionTranslationAZ , positionTranslationEL ).GetAwaiter().GetResult();
- //return sendmovecomand( programmedPeakSpeedAZInt , ACCELERATION , positionTranslationAZ , positionTranslationEL ).GetAwaiter().GetResult(); //.ContinueWith(antecedent => { return antecedent.; });
+ // Also set the MCU's telescope type
+ MCU.setTelescopeType(type);
}
+ ///
+ /// Resets any errors the MCU encounters. This could be for either of the motors.
+ ///
+ public override void ResetMCUErrors()
+ {
+ MCU.ResetMCUErrors();
+ }
- public override bool Move_to_orientation(Orientation target_orientation, Orientation current_orientation)
+ ///
+ /// This will check for any errors present in the MCU's registers.
+ ///
+ /// A list of errors present in the MCU's registers
+ public override List> CheckMCUErrors()
{
- int positionTranslationAZ, positionTranslationEL;
- positionTranslationAZ = ConversionHelper.DegreesToSteps((target_orientation.Azimuth - current_orientation.Azimuth), MotorConstants.GEARING_RATIO_AZIMUTH);
- positionTranslationEL = ConversionHelper.DegreesToSteps((target_orientation.Elevation - current_orientation.Elevation), MotorConstants.GEARING_RATIO_ELEVATION);
+ return MCU.CheckMCUErrors();
+ }
- int EL_Speed = ConversionHelper.DPSToSPS(ConversionHelper.RPMToDPS(0.2), MotorConstants.GEARING_RATIO_ELEVATION);
- int AZ_Speed = ConversionHelper.DPSToSPS( ConversionHelper.RPMToDPS( 0.2 ) , MotorConstants.GEARING_RATIO_AZIMUTH );
+ ///
+ /// This will interrupt the current movement, wait until it has stopped, and then
+ /// end when the movement has stopped.
+ ///
+ /// If no motors are moving when this is called, then it will not wait, and just be
+ /// able to pass through.
+ ///
+ /// Specify whether or not this is a critical movement interrupt and perform and immediate stop
+ /// Specify whether or not this is a software-stop interrupt
+ /// True if it had to wait for a movement, false if it did not have to wait and there is no movement running.
+ public override bool InterruptMovementAndWaitUntilStopped(bool isCriticalMovementInterrupt = false, bool isSoftwareStopInterrupt = false)
+ {
+ bool motorsMoving = MCU.MotorsCurrentlyMoving();
- //(ObjectivePositionStepsAZ - CurrentPositionStepsAZ), (ObjectivePositionStepsEL - CurrentPositionStepsEL)
- Console.WriteLine("degrees target az "+target_orientation.Azimuth + " el " + target_orientation.Elevation);
- Console.WriteLine("degrees curren az " + current_orientation.Azimuth + " el " + current_orientation.Elevation);
+ if (motorsMoving && CurrentMovementPriority != MovementPriority.None)
+ {
+ logger.Info(Utilities.GetTimeStamp() + ": Overriding current movement...");
+ MCU.MovementInterruptFlag = true;
+ // Set corresponding flag depending on whether or not this is a critical movement interrupt
+ if (isCriticalMovementInterrupt)
+ {
+ MCU.CriticalMovementInterruptFlag = true;
+ }
- //return sendmovecomand( EL_Speed * 20 , 50 , positionTranslationAZ , positionTranslationEL ).GetAwaiter().GetResult();
- return send_relative_move( AZ_Speed , EL_Speed ,50, positionTranslationAZ , positionTranslationEL ).GetAwaiter().GetResult();
+ // Set corresponding flag depending on whether or not this is a software stop interrupt
+ if (isSoftwareStopInterrupt)
+ {
+ // Currently necessary to stop Jog movements. Setting the SoftwaeStopInterruptFlag does not
+ // interrupt Jog movements. This should be investigated in the future.
+ if (CurrentMovementPriority == MovementPriority.Jog)
+ {
+ ImmediateStop();
+ }
+ MCU.SoftwareStopInterruptFlag = true;
+ }
+
+ // Wait until motors stop moving or all interrupt flags are set back to false,
+ // meaning the MCU has acknowledged and acted on the interrupt.
+ while (MotorsCurrentlyMoving() && (MCU.MovementInterruptFlag == true || MCU.CriticalMovementInterruptFlag == true || MCU.SoftwareStopInterruptFlag == true)) ;
+
+ MCU.MovementInterruptFlag = false;
+ MCU.CriticalMovementInterruptFlag = false;
+ MCU.SoftwareStopInterruptFlag = false;
+
+ // Ensure there is plenty of time between MCU commands
+ Thread.Sleep(2000);
+ }
+ else
+ {
+ return false;
+ }
+
+ return true;
}
- public override bool Start_jog(RadioTelescopeAxisEnum axis, int speed, bool clockwise)
+ ///
+ /// Checks to see if the motors are currently moving.
+ ///
+ /// Azimuth, elevation, or both.
+ /// True if moving, false if not moving.
+ public override bool MotorsCurrentlyMoving(RadioTelescopeAxisEnum axis = RadioTelescopeAxisEnum.BOTH)
{
- ushort adress = MCUConstants.ACTUAL_MCU_WRITE_REGISTER_START_ADDRESS, dir;
- if (clockwise)
- {
- dir = 0x0080;
- } else dir = 0x0100;
- // reserved msb speed lsb speed acc dcc reserved
- ushort[] data = new ushort[] {dir, 0x0003, 0x0, 0x0, (ushort)(speed >> 16), (ushort)speed, 50, 25, 0x0, 0x0 };// this is a jog comand for a single axis
- RadioTelescopeAxisEnum jogging_axies = Is_jogging();
+ return MCU.MotorsCurrentlyMoving(axis);
+ }
+
+ public override void SetFinalOffset(Orientation finalPos)
+ {
+ MCU.FinalPositionOffset = finalPos;
+ }
+
+ ///
+ /// Gets the direction that the specfied axis is moving.
+ ///
+ /// Azimuth or elevation.
+ /// The direction that the specfied axis is spinning.
+ public override RadioTelescopeDirectionEnum GetRadioTelescopeDirectionEnum(RadioTelescopeAxisEnum axis)
+ {
+ ushort[] directionData;
switch (axis)
{
+ //Axes must be checked independently because the MCU commands for motor moves have the same value for both Az and El
case RadioTelescopeAxisEnum.AZIMUTH:
- {
- break;
- }
+ directionData = MCU.ReadMCURegisters(0, 1);
+ if ((directionData[(int)MCUConstants.MCUOutputRegs.AZ_Status_Bist_MSW] >> (int)MCUConstants.MCUStatusBitsMSW.CCW_Motion & 0b1) == 1)
+ {
+ return RadioTelescopeDirectionEnum.CounterclockwiseOrPositive;
+ }
+
+ if ((directionData[(int)MCUConstants.MCUOutputRegs.AZ_Status_Bist_MSW] >> (int)MCUConstants.MCUStatusBitsMSW.CW_Motion & 0b1) == 1)
+ {
+ return RadioTelescopeDirectionEnum.ClockwiseOrNegative;
+ }
+ break;
+
case RadioTelescopeAxisEnum.ELEVATION:
+ //in practice, only need to check the elevation
+ directionData = MCU.ReadMCURegisters(10, 1);
+
+ if (((directionData[(int)MCUConstants.MCUOutputRegs.EL_Status_Bist_MSW-10] >> (int)MCUConstants.MCUStatusBitsMSW.CCW_Motion) & 0b1) == 1)
{
- adress = MCUConstants.ACTUAL_MCU_WRITE_REGISTER_START_ADDRESS + 10;
- break;
- }
- case RadioTelescopeAxisEnum.BOTH:
- {
- ushort[] data2 = new ushort[data.Length*2];
- data.CopyTo(data2, 0);
- data.CopyTo(data2, data.Length);
- data = data2;
- break;
+ return RadioTelescopeDirectionEnum.CounterclockwiseOrPositive;
}
- default:
+
+ if (((directionData[(int)MCUConstants.MCUOutputRegs.EL_Status_Bist_MSW-10] >> (int)MCUConstants.MCUStatusBitsMSW.CW_Motion) & 0b1) == 1)
{
- throw new ArgumentException("Invalid RadioTelescopeAxisEnum value can be AZIMUTH, ELEVATION or BOTH got: "+axis );
+ return RadioTelescopeDirectionEnum.ClockwiseOrNegative;
}
- }
- MCUModbusMaster.WriteMultipleRegisters(adress, data);
- return true;
- //throw new NotImplementedException();
- }
+ break;
- public async Task send_relative_move( int SpeedAZ , int SpeedEL , ushort ACCELERATION , int positionTranslationAZ , int positionTranslationEL ) {
- bool Sucess = true;
- await MCUModbusMaster.WriteMultipleRegistersAsync( 1024 , MESSAGE_CONTENTS_CLEAR_MOVE );//write a no-op to the mcu
- if(!is_test) {
- Task task = Task.Delay( 100 );//wait to ensure it is porcessed
- await task;
- }
- ushort[] data = {
- 0x0002 , 0x0003, (ushort)((positionTranslationAZ & 0xFFFF0000)>>16),(ushort)(positionTranslationAZ & 0xFFFF),(ushort)((SpeedAZ & 0xFFFF0000)>>16),(ushort)(SpeedAZ & 0xFFFF), ACCELERATION,ACCELERATION ,0,0,
- 0x0002 , 0x0003, (ushort)((positionTranslationEL & 0xFFFF0000)>>16),(ushort)(positionTranslationEL & 0xFFFF),(ushort)((SpeedEL & 0xFFFF0000)>>16),(ushort)(SpeedEL & 0xFFFF), ACCELERATION,ACCELERATION ,0,0
- };
- await MCUModbusMaster.WriteMultipleRegistersAsync( 1024 , data );
- return Sucess;
- }
-
-
- public async Task sendmovecomand( int programmedPeakSpeedAZInt , ushort ACCELERATION , int positionTranslationAZ , int positionTranslationEL ) {
- bool Sucess = true;
- //the mcu registers need to be reset befor a new comand can be set in case the same comand is sent multiple times in a row
- MCUModbusMaster.WriteMultipleRegisters( 1024 , MESSAGE_CONTENTS_CLEAR_MOVE );//write a no-op to the mcu
- if(!is_test) {
- Task task = Task.Delay( 100 );//wait to ensure it is porcessed
- await task;
- }
- ushort[] data = {0, 0x0403,
- (ushort)(programmedPeakSpeedAZInt >> 0x10), (ushort)(programmedPeakSpeedAZInt & 0xFFFF), ACCELERATION, ACCELERATION,
- (ushort)((positionTranslationAZ & 0xFFFF0000)>>16), (ushort)(positionTranslationAZ & 0xFFFF),
- 0, 0, 0, 0,
- (ushort)((positionTranslationEL & 0xFFFF0000)>>16) , (ushort)(positionTranslationEL & 0xFFFF),
- 0, 0, 0, 0, 0, 0
- };
- MCUModbusMaster.WriteMultipleRegisters( 1024 , data );
- return Sucess;
- }
-
- public RadioTelescopeAxisEnum Is_jogging()//////////
- {
- ushort[] data = MCUModbusMaster.ReadHoldingRegisters(MCUConstants.ACTUAL_MCU_WRITE_REGISTER_START_ADDRESS, 20);
- //word 0 and 10 indicate a jog comand for a specific axis however if the position registers(2,3 && 12,13) have non zero value then its a REGISTRATION MOVE
- if ((data[10] == 0x0100|| data[10] == 0x0080) && (data[0] == 0x0100 || data[0] == 0x0080) && data[2] == 0x0 && data[3] == 0x0 && data[12] == 0x0 && data[13] == 0x0)//both jogging
- {
- return RadioTelescopeAxisEnum.BOTH;
- }
- else if ((data[10] == 0x0100 || data[10] == 0x0080) && data[12] == 0x0 && data[13] == 0x0)//el is jogging
- {
- return RadioTelescopeAxisEnum.ELEVATION;
- }
- else if ((data[0] == 0x0100 || data[0] == 0x0080) && data[2] == 0x0 && data[3] == 0x0)//az is jogging
- {
- return RadioTelescopeAxisEnum.AZIMUTH;
+ default:
+ //This function can only accept a single axis (either Az or El)
+ //see comment at top of function
+ throw new ArgumentException();
}
- else return RadioTelescopeAxisEnum.UNKNOWN;
- }
- protected override bool TestIfComponentIsAlive() {
- if(DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() - PLC_last_contact > 3000) {
- return false;
- } else return true;
- }
- public bool workaroundAlive() {
- return TestIfComponentIsAlive();
+ return RadioTelescopeDirectionEnum.None;
}
}
}
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/PLCCommunication/PLCDrivers/ScaleModelPLCDriver.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/PLCCommunication/PLCDrivers/ScaleModelPLCDriver.cs
index 9fecc29d..1c12e5f4 100644
--- a/ControlRoomApplication/ControlRoomApplication/Controllers/PLCCommunication/PLCDrivers/ScaleModelPLCDriver.cs
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/PLCCommunication/PLCDrivers/ScaleModelPLCDriver.cs
@@ -1,358 +1,382 @@
using System;
+using System.Collections.Generic;
+using System.IO.Ports;
using System.Net;
using System.Net.Sockets;
+using System.Threading;
+using System.Threading.Tasks;
+using ControlRoomApplication.Constants;
+using ControlRoomApplication.Controllers.PLCCommunication.PLCDrivers.MCUManager;
+using ControlRoomApplication.Controllers.PLCCommunication.PLCDrivers.MCUManager.Enumerations;
using ControlRoomApplication.Entities;
+using Newtonsoft.Json;
+using static ControlRoomApplication.Constants.MCUConstants;
-namespace ControlRoomApplication.Controllers
-{
- public class ScaleModelPLCDriver : AbstractPLCDriver
- {
- private static readonly log4net.ILog logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
+namespace ControlRoomApplication.Controllers {
- public ScaleModelPLCDriver(IPAddress local_ip_address, IPAddress MCU_ip_address, int MCU_port, int PLC_port) : base(local_ip_address, MCU_ip_address, MCU_port, PLC_port) { }
- public ScaleModelPLCDriver(string local_ip, string MCU_ip, int MCU_port, int PLC_port) : this(IPAddress.Parse(local_ip), IPAddress.Parse(MCU_ip), MCU_port, PLC_port) { }
-
- public bool KillClientManagementThreadFlag;
- public TcpListener PLCTCPListener;
+ public class PLCConnector {
+ ///
+ /// Constructor for the PLCConnector. This constructor should be used for
+ /// connecting to a TCP connection at the localhost 127.0.0.1 address and port 8080.
+ ///
+ public PLCConnector() {
+ ConnectionEndpoint = new IPEndPoint( IPAddress.Parse( PLCConstants.LOCAL_HOST_IP ) , PLCConstants.PORT_8080 );
+ TCPClient = new TcpClient();
+ }
- protected override void HandleClientManagementThread()
- {
- TcpClient AcceptedClient = null;
- byte[] StreamBuffer = new byte[256];
- byte[] ClippedData;
-
- while (!KillClientManagementThreadFlag)
- {
- if (PLCTCPListener.Pending())
- {
- AcceptedClient = PLCTCPListener.AcceptTcpClient();
- logger.Info("[AbstractPLCDriver] Connected to new client.");
-
- NetworkStream ClientStream = AcceptedClient.GetStream();
-
- int Fd;
- while ((!KillClientManagementThreadFlag) && (ClientStream != null))
- {
- if ((!ClientStream.CanRead) || (!ClientStream.DataAvailable))
- {
- continue;
- }
-
- Fd = ClientStream.Read(StreamBuffer, 0, StreamBuffer.Length);
-
- if (Fd == 0)
- {
- continue;
- }
-
- try
- {
- ClippedData = new byte[Fd];
- Array.Copy(StreamBuffer, ClippedData, ClippedData.Length);
-
- if (!ProcessRequest(ClientStream, ClippedData))
- {
- logger.Info("[AbstractPLCDriver] FAILED to write server.");
- }
- else
- {
- //logger.Info("[AbstractPLCDriver] Successfully wrote to server: [{0}]", string.Join(", ", ClippedData));
- //logger.Info("[AbstractPLCDriver] Successfully wrote to server!");
- }
- }
- catch (Exception e)
- {
- if ((e is ArgumentNullException)
- || (e is RankException)
- || (e is ArrayTypeMismatchException)
- || (e is InvalidCastException)
- || (e is ArgumentOutOfRangeException)
- || (e is ArgumentException))
- {
- logger.Info("[AbstractPLCDriver] ERROR: copying buffer array into clipped array {" + Fd + "}, skipping... [" + e.ToString());
- continue;
- }
- else
- {
- // Unexpected exception
- throw e;
- }
- }
- }
- ClientStream.Dispose();
- AcceptedClient.Dispose();
- }
+ ///
+ /// Constructor for the PLCConnector. This constructor should be used for
+ /// connecting to a serial port connection.
+ ///
+ /// The serial port name that should be connected to.
+ public PLCConnector( string portName ) {
+ try {
+ SPort = new SerialPort();
+ SPort.PortName = portName;
+ SPort.BaudRate = PLCConstants.SERIAL_PORT_BAUD_RATE;
+ SPort.Open();
+
+ logger.Info( $"Serial port ({portName}) opened." );
+ } catch(Exception) {
+ logger.Error( "Serial port was already opened." );
}
}
- public bool ProcessRequest(NetworkStream ActiveClientStream, byte[] query)
- {
- int ExpectedSize = query[0] + (256 * query[1]);
- if (query.Length != ExpectedSize)
- {
- throw new ArgumentException(
- "ScaleModelPLCDriverController read a package specifying a size [" + ExpectedSize.ToString() + "], but the actual size was different [" + query.Length + "]."
- );
- }
+ ///
+ /// Constructor for the PLCConecctor. This constructor should be used for
+ /// connecting to a TCP connection at the specified IP address and port.
+ ///
+ /// The IP address, in string format, that should be connected to.
+ /// The port that should be connected to.
+ public PLCConnector( string ip , int port ) {
+ // Initialize Connector with information passed in
+ ConnectionEndpoint = new IPEndPoint( IPAddress.Parse( ip ) , port );
+ TCPClient = new TcpClient();
+ }
+
+ ///
+ /// Connects the control room application to the PLC software through a TCPConnection
+ /// that is established over ethernet.
+ ///
+ /// Returns a bool indicating whether or not the connection established successfully.
+ private bool ConnectToPLC() {
+ // This is one of 3 connect methods that must be used to connect the client
+ // instance with the endpoint (IP address and port number) listed.
+ TCPClient.Connect( ConnectionEndpoint );
+
+ // This gets the stream that the client is connected to above.
+ // Stream is how we will write our data back and forth between
+ // the PLC.
+ Stream = TCPClient.GetStream();
+
+ logger.Info( $"Established TCP connection at ({ConnectionEndpoint.Address}, {ConnectionEndpoint.Port})." );
+ return TCPClient.Client.Connected;
+ }
- byte CommandQueryTypeAndExpectedResponseStatus = query[2];
- byte CommandQueryTypeByte = (byte)(CommandQueryTypeAndExpectedResponseStatus & 0x3F);
- byte ExpectedResponseStatusByte = (byte)(CommandQueryTypeAndExpectedResponseStatus >> 6);
-
- PLCCommandAndQueryTypeEnum CommandQueryTypeEnum = PLCCommandAndQueryTypeConversionHelper.GetFromByte(CommandQueryTypeByte);
- PLCCommandResponseExpectationEnum ExpectedResponseStatusEnum = PLCCommandResponseExpectationConversionHelper.GetFromByte(ExpectedResponseStatusByte);
-
- byte[] FinalResponseContainer;
-
- if (ExpectedResponseStatusEnum == PLCCommandResponseExpectationEnum.FULL_RESPONSE)
- {
- FinalResponseContainer = new byte[]
- {
- 0x13, 0x0,
- 0x0,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
- };
-
- switch (CommandQueryTypeEnum)
- {
- case PLCCommandAndQueryTypeEnum.TEST_CONNECTION:
- {
- FinalResponseContainer[3] = 0x1;
- FinalResponseContainer[2] = 0x1;
- break;
- }
-
- case PLCCommandAndQueryTypeEnum.GET_CURRENT_AZEL_POSITIONS:
- {
- double TestAzimuth = 180.0;
- double TestElevation = 42.0;
-
- Array.Copy(BitConverter.GetBytes(TestAzimuth), 0, FinalResponseContainer, 3, 8);
- Array.Copy(BitConverter.GetBytes(TestElevation), 0, FinalResponseContainer, 11, 8);
-
- FinalResponseContainer[2] = 0x1;
-
- break;
- }
-
- case PLCCommandAndQueryTypeEnum.GET_CURRENT_LIMIT_SWITCH_STATUSES:
- {
- PLCLimitSwitchStatusEnum StatusAzimuthUnderRotation = PLCLimitSwitchStatusEnum.WITHIN_SAFE_LIMITS;
- PLCLimitSwitchStatusEnum StatusAzimuthOverRotation = PLCLimitSwitchStatusEnum.WITHIN_SAFE_LIMITS;
- PLCLimitSwitchStatusEnum StatusElevationUnderRotation = PLCLimitSwitchStatusEnum.WITHIN_SAFE_LIMITS;
- PLCLimitSwitchStatusEnum StatusElevationOverRotation = PLCLimitSwitchStatusEnum.WITHIN_SAFE_LIMITS;
-
- int PacketSum =
- PLCLimitSwitchStatusConversionHelper.ConvertToByte(StatusElevationOverRotation)
- + (PLCLimitSwitchStatusConversionHelper.ConvertToByte(StatusElevationUnderRotation) * 0x4)
- + (PLCLimitSwitchStatusConversionHelper.ConvertToByte(StatusAzimuthOverRotation) * 0x10)
- + (PLCLimitSwitchStatusConversionHelper.ConvertToByte(StatusAzimuthUnderRotation) * 0x40)
- ;
-
- FinalResponseContainer[3] = (byte)PacketSum;
- FinalResponseContainer[2] = 0x1;
-
- break;
- }
-
- case PLCCommandAndQueryTypeEnum.GET_CURRENT_SAFETY_INTERLOCK_STATUS:
- {
- FinalResponseContainer[3] = PLCSafetyInterlockStatusConversionHelper.ConvertToByte(PLCSafetyInterlockStatusEnum.LOCKED);
- FinalResponseContainer[2] = 0x1;
- break;
- }
-
- default:
- {
- throw new ArgumentException("Invalid PLCCommandAndQueryTypeEnum value seen while expecting a response: " + CommandQueryTypeEnum.ToString());
- }
+ ///
+ /// Writes a message to the network stream that is connecting this application
+ /// to the application running the PLC hardware.
+ ///
+ /// A string that represents the state of the object.
+ public void WriteMessage( string message ) {
+ // Convert the message passed in into a byte[] array.
+ Data = System.Text.Encoding.ASCII.GetBytes( message );
+
+ // If the connection to the PLC is successful, get the NetworkStream
+ // that is being used and write to it.
+ if(ConnectToPLC()) {
+ try {
+ Stream = TCPClient.GetStream();
+
+ Stream.Write( Data , 0 , Data.Length );
+
+ logger.Info( "Sent message to PLC over TCP." );
+ } catch(SocketException e) {
+ Console.WriteLine( $"Encountered a socket exception." );
+ logger.Error( $"There was an issue with the socket: {e.Message}." );
}
}
- else if (ExpectedResponseStatusEnum == PLCCommandResponseExpectationEnum.MINOR_RESPONSE)
- {
- FinalResponseContainer = new byte[]
- {
- 0x3, 0x0, 0x0
- };
-
- switch (CommandQueryTypeEnum)
- {
- case PLCCommandAndQueryTypeEnum.CANCEL_ACTIVE_OBJECTIVE_AZEL_POSITION:
- case PLCCommandAndQueryTypeEnum.SHUTDOWN:
- case PLCCommandAndQueryTypeEnum.CALIBRATE:
- {
- FinalResponseContainer[2] = 0x1;
- break;
- }
-
- case PLCCommandAndQueryTypeEnum.SET_OBJECTIVE_AZEL_POSITION:
- {
- double NextAZ, NextEL;
-
- try
- {
- NextAZ = BitConverter.ToDouble(query, 3);
- NextEL = BitConverter.ToDouble(query, 11);
- }
- catch (Exception e)
- {
- if ((e is ArgumentException) || (e is ArgumentNullException) || (e is ArgumentOutOfRangeException))
- {
- // This error code means that the data could not be converted into a double-precision floating point
- FinalResponseContainer[2] = 0x2;
- break;
- }
- else
- {
- // Unexpected exception
- throw e;
- }
- }
-
- if ((NextAZ < 0) || (NextAZ > 360))
- {
- // This error code means that the objective azimuth position is invalid
- FinalResponseContainer[2] = 0x3;
- break;
- }
-
- if ((NextEL < 0) || (NextEL > 90))
- {
- // This error code means that the objective elevation position is invalid
- FinalResponseContainer[2] = 0x4;
- break;
- }
-
- // Otherwise, this is valid
- // TODO: Perform task(s) to set objective orientation!
-
- FinalResponseContainer[2] = 0x1;
- break;
- }
-
- default:
- {
- throw new ArgumentException("Invalid PLCCommandAndQueryTypeEnum value seen while NOT expecting a response: " + CommandQueryTypeEnum.ToString());
- }
+ }
+
+ ///
+ /// Receives messages from a TCP connection from the IPEndpoint that TCPClient
+ /// is connected to.
+ ///
+ /// A string that indicates the state of the operation.
+ public string ReceiveMessage() {
+ // Create a new byte[] array and initialize the string
+ // we will send back
+ Data = new byte[256];
+ string responseData = string.Empty;
+
+ if(ConnectToPLC()) {
+ int i;
+ try {
+ while((i = Stream.Read( Data , 0 , Data.Length )) != 0) {
+ Message = System.Text.Encoding.ASCII.GetString( Data , 0 , i );
+ }
+
+ logger.Info( "Message received from PLC." );
+ } catch(SocketException e) {
+ Console.WriteLine( "Encountered a socket exception." );
+ logger.Error( $"There was an issue with the socket {e.Message}" );
+ } finally {
+ DisconnectFromPLC();
+ logger.Info( "Disconnected from PLC." );
}
}
- else
- {
- throw new ArgumentException("Invalid PLCCommandResponseExpectationEnum value seen while processing client request in ScaleModelPLCDriver: " + ExpectedResponseStatusEnum.ToString());
- }
- return AttemptToWriteDataToServer(ActiveClientStream, FinalResponseContainer);
+ return Message;
}
+ ///
+ /// Disconnects the TCP connection that was established to the PLC.
+ ///
+ public void DisconnectFromPLC() {
+ // Call the dispose() method to close the stream and connection.
+ TCPClient.Dispose();
+ logger.Info( "Disposed of the TCP Client." );
+ }
- protected bool AttemptToWriteDataToServer(NetworkStream ActiveClientStream, byte[] ResponseData)
- {
- try
- {
- ActiveClientStream.Write(ResponseData, 0, ResponseData.Length);
- }
- catch (Exception e)
- {
- if ((e is ArgumentNullException) || (e is ArgumentOutOfRangeException) || (e is System.IO.IOException) || (e is ObjectDisposedException))
- {
- logger.Info("[AbstractPLCDriver] ERROR: writing back to client with the PLC's response {" + ResponseData.ToString() + "}");
- return false;
- }
- }
+ //*** These methods will be for the arduino scale model. ***//
+
+ ///
+ /// Closes the serial port that was opened in SPort.
+ ///
+ public void CloseSerialPort() {
+ SPort.Close();
+ logger.Info( "Serial port has been closed." );
+ }
+
+ ///
+ /// Gets a message from the specified serial port in SPort.
+ ///
+ /// Returns a string that was read from the serial port.
+ public string GetSerialPortMessage() {
+ Message = string.Empty;
+ // Read all existing bytes in the stream.
+ Message = SPort.ReadExisting();
+
+ logger.Info( "Message received from Arduino." );
+ return Message;
+ }
+
+ public bool SendSerialPortMessage( string jsonOrientation ) {
+ Data = System.Text.Encoding.ASCII.GetBytes( jsonOrientation );
+ Thread.Sleep( 10 );
+ SPort.Write( Data , 0 , Data.Length );
+ Thread.Sleep( 10 );
+ logger.Info( "Message sent to Arduino" );
return true;
}
- public override bool StartAsyncAcceptingClients()
- {
- throw new NotImplementedException();
+ // Getters/Setters for TCP/IP connection
+ public TcpClient TCPClient { get; set; }
+ public IPEndPoint ConnectionEndpoint { get; set; }
+ public NetworkStream Stream { get; set; }
+ public byte[] Data { get; set; }
+ public string Message { get; set; }
+
+ // Getters/Setters for Serial Port connection (for arduino scale model)
+ public SerialPort SPort { get; set; }
+ private static readonly log4net.ILog logger =
+ log4net.LogManager.GetLogger( System.Reflection.MethodBase.GetCurrentMethod().DeclaringType );
+ }
+
+ public class ScaleModelPLCDriver : AbstractPLCDriver {
+ private static readonly log4net.ILog logger = log4net.LogManager.GetLogger( System.Reflection.MethodBase.GetCurrentMethod().DeclaringType );
+ public PLCConnector PlcConnector { get; set; }
+
+
+ public ScaleModelPLCDriver( string local_ip , string MCU_ip , int MCU_port , int PLC_port ) :base( local_ip , MCU_ip, MCU_port, PLC_port ) {
+ Console.WriteLine( MCU_ip );
}
- public override bool RequestStopAsyncAcceptingClientsAndJoin()
+ public override MovementPriority CurrentMovementPriority { get; set; }
+
+ public override void setregvalue(ushort adr, ushort value)
{
throw new NotImplementedException();
}
- public override void Bring_down()
- {
- throw new NotImplementedException();
+
+
+ public override void HandleClientManagementThread() {}
+
+
+ public override bool StartAsyncAcceptingClients() {
+ return true;
}
- public override bool Test_Conection()
- {
- throw new NotImplementedException();
+ public override bool RequestStopAsyncAcceptingClientsAndJoin() {
+ return true;
}
- public override Orientation read_Position()
- {
- throw new NotImplementedException();
+ public override void Bring_down() {
}
- public override bool Cancle_move()
- {
- throw new NotImplementedException();
+ public override bool Test_Connection() {
+ return true;
}
- public override bool Shutdown_PLC_MCU()
- {
- throw new NotImplementedException();
+ public override Orientation GetMotorEncoderPosition() {
+ return new Orientation();
}
- public override bool Calibrate()
- {
- throw new NotImplementedException();
+ public override MovementResult Cancel_move() {
+ return MovementResult.None;
+
+ }
+
+ public override bool Configure_MCU( double startSpeedAzimuth , double startSpeedElevation , int homeTimeoutAzimuth , int homeTimeoutElevation ) {
+ return true;
}
- public override bool Configure_MCU(int startSpeedAzimuth, int startSpeedElevation, int homeTimeoutAzimuth, int homeTimeoutElevation)
+ public override MovementResult ControlledStop() {
+ return MovementResult.None;
+
+ }
+
+ public override MovementResult ImmediateStop() {
+ return MovementResult.None;
+
+ }
+
+ public MovementResult SendRelativeMove(int SpeedAZ, int SpeedEL, int positionTranslationAZ, int positionTranslationEL) {
+ // Move the scale model's azimuth motor on com3 and its elevation on com4
+ // make sure there is a delay in this thread for enough time to have the arduino
+ // move the first motor (azimuth)
+ string jsonOrientation = JsonConvert.SerializeObject( new {
+ CMD = "relMove",
+ az =positionTranslationAZ,
+ el = positionTranslationEL
+ } );
+ PlcConnector = new PLCConnector( "COM12" );
+ PlcConnector.SendSerialPortMessage( jsonOrientation );
+
+ // Wait for the arduinos to send back a response
+ // in the arduino code, as of milestone 2, the response is a string: "finished"
+ var state = string.Empty;
+ //state = PlcConnector.GetSerialPortMessage();
+ PlcConnector.CloseSerialPort();
+ // Print the state of the move operation to the console.
+ //Console.WriteLine(state);
+
+ return MovementResult.Success;
+ }
+
+ public override MovementResult RelativeMove(int programmedPeakSpeedAZInt, int programmedPeakSpeedELInt, int positionTranslationAZ, int positionTranslationEL, Orientation targetOrientation) {
+ /*
+ if(Plc.OutgoingOrientation.Azimuth < PLCConstants.RIGHT_ASCENSION_LOWER_LIMIT || Plc.OutgoingOrientation.Azimuth > PLCConstants.RIGHT_ASCENSION_UPPER_LIMIT) {
+ logger.Error( $"Azimuth ({Plc.OutgoingOrientation.Azimuth}) was out of range." );
+ throw new System.Exception();
+ } else if(Plc.OutgoingOrientation.Elevation < PLCConstants.DECLINATION_LOWER_LIMIT || Plc.OutgoingOrientation.Elevation > PLCConstants.DECLINATION_UPPER_LIMIT) {
+ logger.Error( $"Elevation ({Plc.OutgoingOrientation.Elevation} was out of range.)" );
+ throw new System.Exception();
+ }
+ */
+ // Convert orientation object to a json string
+ //string jsonOrientation = JsonConvert.SerializeObject( Plc.OutgoingOrientation );
+ return SendRelativeMove(programmedPeakSpeedAZInt, programmedPeakSpeedELInt, positionTranslationAZ, positionTranslationEL);
+
+ }
+
+
+
+ public override MovementResult MoveToOrientation(Orientation target_orientation, Orientation current_orientation)
{
+ int positionTranslationAZ, positionTranslationEL;
+ positionTranslationAZ = ConversionHelper.DegreesToSteps((target_orientation.Azimuth - current_orientation.Azimuth), MotorConstants.GEARING_RATIO_AZIMUTH);
+ positionTranslationEL = ConversionHelper.DegreesToSteps((target_orientation.Elevation - current_orientation.Elevation), MotorConstants.GEARING_RATIO_ELEVATION);
+
+ int EL_Speed = ConversionHelper.DPSToSPS(ConversionHelper.RPMToDPS(0.2), MotorConstants.GEARING_RATIO_ELEVATION);
+ int AZ_Speed = ConversionHelper.DPSToSPS(ConversionHelper.RPMToDPS(0.2), MotorConstants.GEARING_RATIO_AZIMUTH);
+
+ //(ObjectivePositionStepsAZ - CurrentPositionStepsAZ), (ObjectivePositionStepsEL - CurrentPositionStepsEL)
+ Console.WriteLine("degrees target az " + target_orientation.Azimuth + " el " + target_orientation.Elevation);
+ Console.WriteLine("degrees curren az " + current_orientation.Azimuth + " el " + current_orientation.Elevation);
+
+
+ //return sendmovecomand( EL_Speed * 20 , 50 , positionTranslationAZ , positionTranslationEL ).GetAwaiter().GetResult();
+ return SendRelativeMove(AZ_Speed, EL_Speed, positionTranslationAZ, positionTranslationEL);
+
+ }
+
+ public override MovementResult StartBothAxesJog(double azSpeed, RadioTelescopeDirectionEnum azDirection, double elSpeed, RadioTelescopeDirectionEnum elDirection) {
throw new NotImplementedException();
+
}
- public override bool Controled_stop(RadioTelescopeAxisEnum axis, bool both)
- {
+ public override bool Get_interlock_status() {
+ return true;
+
+ }
+
+ public override bool[] GET_MCU_Status( RadioTelescopeAxisEnum axis ) {//set
+ bool[] stuf = new bool[33];
+ for(int i = 0; i < 32; i++) {
+ stuf[i] = true;
+ }
+ return stuf;
+ }
+
+ public override bool TestIfComponentIsAlive() {
+ return true;
+
+ }
+
+ public override MovementResult HomeTelescope() {
throw new NotImplementedException();
}
- public override bool Immediade_stop()
+ public override ushort getregvalue(ushort adr)
{
throw new NotImplementedException();
}
- public override bool relative_move(int programmedPeakSpeedAZInt, ushort ACCELERATION, int positionTranslationAZ, int positionTranslationEL)
+ public override void setTelescopeType(RadioTelescopeTypeEnum type)
{
throw new NotImplementedException();
}
- public override bool Move_to_orientation(Orientation target_orientation, Orientation current_orientation)
+ ///
+ /// Resets any errors the MCU encounters. This could be for either of the motors.
+ /// This has not been implemented on the scale model.
+ ///
+ public override void ResetMCUErrors()
{
throw new NotImplementedException();
}
- public override bool Start_jog(RadioTelescopeAxisEnum axis, int speed, bool clockwise)
+ ///
+ /// This will check for any errors present in the MCU's registers.
+ ///
+ /// A list of errors present in the MCU's registers
+ public override List> CheckMCUErrors()
{
throw new NotImplementedException();
}
- public override bool Get_interlock_status()
+ public override bool InterruptMovementAndWaitUntilStopped(bool isCriticalMovementInterrupt = false, bool isSoftwareStopInterrupt = false)
{
throw new NotImplementedException();
}
- public override bool[] Get_Limit_switches()
+ public override bool MotorsCurrentlyMoving(RadioTelescopeAxisEnum axis = RadioTelescopeAxisEnum.BOTH)
{
throw new NotImplementedException();
}
- public override bool[] GET_MCU_Status()
+ public override void SetFinalOffset(Orientation finalPos)
{
throw new NotImplementedException();
}
- protected override bool TestIfComponentIsAlive() {
+ public override RadioTelescopeDirectionEnum GetRadioTelescopeDirectionEnum(RadioTelescopeAxisEnum axis)
+ {
throw new NotImplementedException();
}
-
}
}
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/PLCCommunication/PLCDrivers/SimulationPLCDriver.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/PLCCommunication/PLCDrivers/SimulationPLCDriver.cs
index d1835980..09f3ebe7 100644
--- a/ControlRoomApplication/ControlRoomApplication/Controllers/PLCCommunication/PLCDrivers/SimulationPLCDriver.cs
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/PLCCommunication/PLCDrivers/SimulationPLCDriver.cs
@@ -1,9 +1,14 @@
using System;
+using System.Collections.Generic;
using System.Net.Sockets;
using System.Threading;
+using System.Threading.Tasks;
using ControlRoomApplication.Constants;
+using ControlRoomApplication.Controllers.PLCCommunication.PLCDrivers.MCUManager;
+using ControlRoomApplication.Controllers.PLCCommunication.PLCDrivers.MCUManager.Enumerations;
using ControlRoomApplication.Entities;
using ControlRoomApplication.Simulators.Hardware.PLC_MCU;
+using static ControlRoomApplication.Constants.MCUConstants;
namespace ControlRoomApplication.Controllers
{
@@ -12,21 +17,29 @@ public class SimulationPLCDriver : AbstractPLCDriver
private static readonly log4net.ILog logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
private Simulation_control_pannel SimMCU;
- private ProductionPLCDriver driver;
-
- public SimulationPLCDriver(string local_ip, string MCU_ip, int MCU_port, int PLC_port) : base(local_ip, MCU_ip, MCU_port, PLC_port)
- {
- if (MCU_port== PLC_port)//cant have 2 servers on the same port and ip
- {
- MCU_port++;
- }
- SimMCU = new Simulation_control_pannel(local_ip, MCU_ip, MCU_port, PLC_port);
+ public ProductionPLCDriver driver;
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// if this is true the sim telescope will teleport to its final position
+ public SimulationPLCDriver(string local_ip, string MCU_ip, int MCU_port, int PLC_port, bool startPLC,bool is_Test ) : base(local_ip, MCU_ip, MCU_port, PLC_port )
+ {
+ SimMCU = new Simulation_control_pannel(local_ip, MCU_ip, MCU_port, PLC_port, is_Test);
Thread.Sleep(1000);//wait for server in simMcu to come up
driver = new ProductionPLCDriver(local_ip, MCU_ip, MCU_port, PLC_port);
- driver.StartAsyncAcceptingClients();
+ if(startPLC) {
+ driver.StartAsyncAcceptingClients();
+ }
+ SimMCU.startPLC();
+ driver.set_is_test( is_Test );
}
-
+ public override MovementPriority CurrentMovementPriority { get { return driver.CurrentMovementPriority; } set { driver.CurrentMovementPriority = value; } }
public override bool RequestStopAsyncAcceptingClientsAndJoin()
{
@@ -38,9 +51,9 @@ public override bool StartAsyncAcceptingClients()
return driver.StartAsyncAcceptingClients();
}
- protected override void HandleClientManagementThread()
+ public override void HandleClientManagementThread()
{
- throw new NotImplementedException();
+ driver.HandleClientManagementThread();
}
public override void Bring_down()
@@ -49,79 +62,118 @@ public override void Bring_down()
driver.Bring_down();
}
- public override bool Test_Conection()
+ public override bool Test_Connection()
{
- return driver.Test_Conection();
+ return driver.Test_Connection();
}
- public override Orientation read_Position()
+ public override Orientation GetMotorEncoderPosition()
{
- return driver.read_Position();
+ return driver.GetMotorEncoderPosition();
}
- public override bool Cancle_move()
+ public override MovementResult Cancel_move()
{
- return driver.Cancle_move();
+ return driver.Cancel_move();
}
- public override bool Shutdown_PLC_MCU()
+ public override bool Configure_MCU(double startSpeedAzimuth, double startSpeedElevation, int homeTimeoutAzimuth, int homeTimeoutElevation)
{
- return driver.Shutdown_PLC_MCU();
+ return driver.Configure_MCU(startSpeedAzimuth, startSpeedElevation, homeTimeoutAzimuth, homeTimeoutElevation);
}
- public override bool Calibrate()
+ public override MovementResult ControlledStop()
{
- return driver.Calibrate();
+ return driver.ControlledStop();
}
- public override bool Configure_MCU(int startSpeedAzimuth, int startSpeedElevation, int homeTimeoutAzimuth, int homeTimeoutElevation)
+ public override MovementResult ImmediateStop()
{
- return driver.Configure_MCU(startSpeedAzimuth, startSpeedElevation, homeTimeoutAzimuth, homeTimeoutElevation);
+ return driver.ImmediateStop();
}
- public override bool Controled_stop(RadioTelescopeAxisEnum axis, bool both)
+ public override MovementResult RelativeMove(int programmedPeakSpeedAZInt, int programmedPeakSpeedELInt, int positionTranslationAZ, int positionTranslationEL, Orientation targetOrientation)
{
- return driver.Controled_stop(axis , both );
+ return driver.RelativeMove(programmedPeakSpeedAZInt, programmedPeakSpeedELInt, positionTranslationAZ, positionTranslationEL, targetOrientation);
}
- public override bool Immediade_stop()
+ public override MovementResult MoveToOrientation(Orientation target_orientation, Orientation current_orientation)
{
- return driver.Immediade_stop();
+ return driver.MoveToOrientation(target_orientation, current_orientation);
}
- public override bool relative_move(int programmedPeakSpeedAZInt, ushort ACCELERATION, int positionTranslationAZ, int positionTranslationEL)
+ public override MovementResult StartBothAxesJog(double azSpeed, RadioTelescopeDirectionEnum azDirection, double elSpeed, RadioTelescopeDirectionEnum elDirection) {
+ return driver.StartBothAxesJog(azSpeed, azDirection, elSpeed, elDirection);
+ }
+
+ public override bool Get_interlock_status()
{
- return driver.relative_move(programmedPeakSpeedAZInt, ACCELERATION, positionTranslationAZ, positionTranslationEL);
+ return driver.Get_interlock_status();
}
- public override bool Move_to_orientation(Orientation target_orientation, Orientation current_orientation)
+ public override bool[] GET_MCU_Status( RadioTelescopeAxisEnum axis )
{
- return driver.Move_to_orientation(target_orientation, current_orientation);
+ return driver.GET_MCU_Status( axis );
+ }
+
+ public override bool TestIfComponentIsAlive() {
+ return driver.TestIfComponentIsAlive();
+ }
+
+ public override MovementResult HomeTelescope() {
+ return driver.HomeTelescope();
}
- public override bool Start_jog(RadioTelescopeAxisEnum axis, int speed, bool clockwise)
+ public override void setregvalue(ushort adr, ushort value)
{
- return driver.Start_jog(axis, speed, clockwise);
+ driver.setregvalue(adr, value);
}
- public override bool Get_interlock_status()
+ public override ushort getregvalue(ushort adr)
{
- return driver.Get_interlock_status();
+ return driver.getregvalue(adr);
+ }
+
+ public override void setTelescopeType(RadioTelescopeTypeEnum type)
+ {
+ driver.setTelescopeType(type);
+ }
+
+ ///
+ /// Resets any errors the MCU encounters. This could be for either of the motors.
+ ///
+ public override void ResetMCUErrors()
+ {
+ driver.ResetMCUErrors();
}
- public override bool[] Get_Limit_switches()
+ ///
+ /// This will check for any errors present in the MCU's registers.
+ ///
+ /// A list of errors present in the MCU's registers
+ public override List> CheckMCUErrors()
{
- return driver.Get_Limit_switches();
+ return driver.CheckMCUErrors();
}
- public override bool[] GET_MCU_Status()
+ public override bool InterruptMovementAndWaitUntilStopped(bool isCriticalMovementInterrupt = false, bool isSoftwareStopInterrupt = false)
{
- return driver.GET_MCU_Status();
+ return driver.InterruptMovementAndWaitUntilStopped(isCriticalMovementInterrupt, isSoftwareStopInterrupt);
}
- protected override bool TestIfComponentIsAlive() {
- return driver.workaroundAlive();
+ public override bool MotorsCurrentlyMoving(RadioTelescopeAxisEnum axis = RadioTelescopeAxisEnum.BOTH)
+ {
+ return driver.MotorsCurrentlyMoving(axis);
}
+ public override void SetFinalOffset(Orientation finalPos)
+ {
+ driver.SetFinalOffset(finalPos);
+ }
+
+ public override RadioTelescopeDirectionEnum GetRadioTelescopeDirectionEnum(RadioTelescopeAxisEnum axis)
+ {
+ return driver.GetRadioTelescopeDirectionEnum(axis);
+ }
}
}
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/PLCCommunication/PLCDrivers/TestPLCDriver.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/PLCCommunication/PLCDrivers/TestPLCDriver.cs
index 4487ae11..21be55f9 100644
--- a/ControlRoomApplication/ControlRoomApplication/Controllers/PLCCommunication/PLCDrivers/TestPLCDriver.cs
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/PLCCommunication/PLCDrivers/TestPLCDriver.cs
@@ -2,427 +2,21 @@
using System.Net;
using System.Net.Sockets;
using System.Threading;
+using System.Threading.Tasks;
using ControlRoomApplication.Constants;
using ControlRoomApplication.Entities;
using ControlRoomApplication.Simulators.Hardware.PLC_MCU;
namespace ControlRoomApplication.Controllers
{
- public class TestPLCDriver : AbstractPLCDriver
- {
+ public class TestPLCDriver : SimulationPLCDriver {
private static readonly log4net.ILog logger =
- log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
+ log4net.LogManager.GetLogger( System.Reflection.MethodBase.GetCurrentMethod().DeclaringType );
- public Orientation CurrentOrientation { get; private set; }
- public bool KillClientManagementThreadFlag;
- public TcpListener PLCTCPListener;
+ ///
+ public TestPLCDriver( string local_ip , string MCU_ip , int MCU_port , int PLC_port , bool startPLC ) : base( local_ip , MCU_ip , MCU_port , PLC_port , startPLC , true ) {
- private Test_control_pannel TestMCU;
- private ProductionPLCDriver driver;
-
- public TestPLCDriver(string local_ip, string MCU_ip, int MCU_port, int PLC_port) : base(local_ip, MCU_ip, MCU_port, PLC_port)
- {
- CurrentOrientation = new Orientation();
-
- if (MCU_port == PLC_port)
- {
- MCU_port++;
- }
- TestMCU = new Test_control_pannel(local_ip, MCU_ip, MCU_port, PLC_port);
- Thread.Sleep(100);
- driver = new ProductionPLCDriver(local_ip, MCU_ip, MCU_port, PLC_port);
- driver.set_is_test(true);
- Thread.Sleep(1000);
- //driver.StartAsyncAcceptingClients();
- }
-
-
- public void setSaftyInterlock() {
- TestMCU.PLCModbusMaster.WriteMultipleRegisters( (ushort)PLC_modbus_server_register_mapping.Safty_INTERLOCK - 1 , new ushort[] { 12 } );
- }
-
-
-
- public override bool StartAsyncAcceptingClients()
- {
- return driver.StartAsyncAcceptingClients();
- }
-
- public override bool RequestStopAsyncAcceptingClientsAndJoin()
- {
- return driver.RequestStopAsyncAcceptingClientsAndJoin();
- }
-
- public override void Bring_down()
- {
- TestMCU.Bring_down();
- driver.Bring_down();
- }
-
- public override bool Test_Conection()
- {
- return driver.Test_Conection();
- }
-
- public override Orientation read_Position()
- {
- return driver.read_Position();
- }
-
- public override bool Cancle_move()
- {
- return driver.Cancle_move();
- }
-
- public override bool Shutdown_PLC_MCU()
- {
- return driver.Shutdown_PLC_MCU();
- }
-
- public override bool Calibrate()
- {
- return driver.Calibrate();
- }
-
- public override bool Configure_MCU(int startSpeedAzimuth, int startSpeedElevation, int homeTimeoutAzimuth, int homeTimeoutElevation)
- {
- return driver.Configure_MCU(startSpeedAzimuth, startSpeedElevation, homeTimeoutAzimuth, homeTimeoutElevation);
- }
-
- public override bool Controled_stop(RadioTelescopeAxisEnum axis, bool both)
- {
- return driver.Controled_stop( axis, both);
- }
-
- public override bool Immediade_stop()
- {
- return driver.Immediade_stop();
- }
-
- public override bool relative_move(int programmedPeakSpeedAZInt, ushort ACCELERATION, int positionTranslationAZ, int positionTranslationEL)
- {
- return driver.relative_move(programmedPeakSpeedAZInt, ACCELERATION, positionTranslationAZ, positionTranslationEL);
- }
-
- public override bool Move_to_orientation(Orientation target_orientation, Orientation current_orientation)
- {
- return driver.Move_to_orientation(target_orientation, current_orientation);
- }
-
- public override bool Start_jog(RadioTelescopeAxisEnum axis, int speed, bool clockwise)
- {
- return driver.Start_jog(axis, speed, clockwise);
- }
-
- public override bool Get_interlock_status() {
- //TestMCU.PLCModbusMaster.WriteSingleRegister( (ushort)PLC_modbus_server_register_mapping.Safty_INTERLOCK - 1 , 123 );
- return driver.Get_interlock_status();
- }
-
-
- public override bool[] Get_Limit_switches()
- {
- return driver.Get_Limit_switches();
- }
-
- public override bool[] GET_MCU_Status()
- {
- return driver.GET_MCU_Status();
- }
-
- protected override bool TestIfComponentIsAlive() {
- return true;
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- public bool ProcessRequest(NetworkStream ActiveClientStream, byte[] query)
- {
- int ExpectedSize = query[0] + (256 * query[1]);
- if (query.Length != ExpectedSize)
- {
- throw new ArgumentException(
- "TestPLCDriverController read a package specifying a size [" + ExpectedSize.ToString() + "], but the actual size was different [" + query.Length + "]."
- );
- }
-
- byte CommandQueryTypeAndExpectedResponseStatus = query[2];
- byte CommandQueryTypeByte = (byte)(CommandQueryTypeAndExpectedResponseStatus & 0x3F);
- byte ExpectedResponseStatusByte = (byte)(CommandQueryTypeAndExpectedResponseStatus >> 6);
-
- PLCCommandAndQueryTypeEnum CommandQueryTypeEnum = PLCCommandAndQueryTypeConversionHelper.GetFromByte(CommandQueryTypeByte);
- PLCCommandResponseExpectationEnum ExpectedResponseStatusEnum = PLCCommandResponseExpectationConversionHelper.GetFromByte(ExpectedResponseStatusByte);
-
- byte[] FinalResponseContainer;
-
- if (ExpectedResponseStatusEnum == PLCCommandResponseExpectationEnum.FULL_RESPONSE)
- {
- FinalResponseContainer = new byte[]
- {
- 0x13, 0x0,
- 0x0,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
- };
-
- switch (CommandQueryTypeEnum)
- {
- case PLCCommandAndQueryTypeEnum.TEST_CONNECTION:
- {
- FinalResponseContainer[3] = 0x1;
- FinalResponseContainer[2] = 0x1;
- break;
- }
-
- case PLCCommandAndQueryTypeEnum.GET_CURRENT_AZEL_POSITIONS:
- {
- Array.Copy(BitConverter.GetBytes(CurrentOrientation.Azimuth), 0, FinalResponseContainer, 3, 8);
- Array.Copy(BitConverter.GetBytes(CurrentOrientation.Elevation), 0, FinalResponseContainer, 11, 8);
-
- FinalResponseContainer[2] = 0x1;
-
- break;
- }
-
- case PLCCommandAndQueryTypeEnum.GET_CURRENT_LIMIT_SWITCH_STATUSES:
- {
- double CurrentAZ = CurrentOrientation.Azimuth;
- double CurrentEL = CurrentOrientation.Elevation;
-
- double ThresholdAZ = MiscellaneousHardwareConstants.LIMIT_SWITCH_AZ_THRESHOLD_DEGREES;
- double ThresholdEL = MiscellaneousHardwareConstants.LIMIT_SWITCH_EL_THRESHOLD_DEGREES;
-
- // Subtracting out those 2 degrees is because of our actual rotational limits of (-2 : 362) and (-2 : 92) degrees in azimuth and elevation respectively
- PLCLimitSwitchStatusEnum StatusAzimuthUnderRotation = (CurrentAZ < (ThresholdAZ - 2.0)) ? PLCLimitSwitchStatusEnum.WITHIN_WARNING_LIMITS : PLCLimitSwitchStatusEnum.WITHIN_SAFE_LIMITS;
- PLCLimitSwitchStatusEnum StatusAzimuthOverRotation = (CurrentAZ > (360 + ThresholdAZ - 2.0)) ? PLCLimitSwitchStatusEnum.WITHIN_WARNING_LIMITS : PLCLimitSwitchStatusEnum.WITHIN_SAFE_LIMITS;
- PLCLimitSwitchStatusEnum StatusElevationUnderRotation = (CurrentEL < (ThresholdEL - 2.0)) ? PLCLimitSwitchStatusEnum.WITHIN_WARNING_LIMITS : PLCLimitSwitchStatusEnum.WITHIN_SAFE_LIMITS;
- PLCLimitSwitchStatusEnum StatusElevationOverRotation = (CurrentEL > (90 + ThresholdEL - 2.0)) ? PLCLimitSwitchStatusEnum.WITHIN_WARNING_LIMITS : PLCLimitSwitchStatusEnum.WITHIN_SAFE_LIMITS;
-
- int PacketSum =
- PLCLimitSwitchStatusConversionHelper.ConvertToByte(StatusElevationOverRotation)
- + (PLCLimitSwitchStatusConversionHelper.ConvertToByte(StatusElevationUnderRotation) * 0x4)
- + (PLCLimitSwitchStatusConversionHelper.ConvertToByte(StatusAzimuthOverRotation) * 0x10)
- + (PLCLimitSwitchStatusConversionHelper.ConvertToByte(StatusAzimuthUnderRotation) * 0x40)
- ;
-
- FinalResponseContainer[3] = (byte)PacketSum;
- FinalResponseContainer[2] = 0x1;
-
- break;
- }
-
- case PLCCommandAndQueryTypeEnum.GET_CURRENT_SAFETY_INTERLOCK_STATUS:
- {
- FinalResponseContainer[3] = PLCSafetyInterlockStatusConversionHelper.ConvertToByte(PLCSafetyInterlockStatusEnum.LOCKED);
- FinalResponseContainer[2] = 0x1;
- break;
- }
-
- default:
- {
- throw new ArgumentException("Invalid PLCCommandAndQueryTypeEnum value seen while expecting a response: " + CommandQueryTypeEnum.ToString());
- }
- }
- }
- else if (ExpectedResponseStatusEnum == PLCCommandResponseExpectationEnum.MINOR_RESPONSE)
- {
- FinalResponseContainer = new byte[]
- {
- 0x3, 0x0, 0x0
- };
-
- switch (CommandQueryTypeEnum)
- {
- case PLCCommandAndQueryTypeEnum.CANCEL_ACTIVE_OBJECTIVE_AZEL_POSITION:
- case PLCCommandAndQueryTypeEnum.SHUTDOWN:
- case PLCCommandAndQueryTypeEnum.CALIBRATE:
- {
- FinalResponseContainer[2] = 0x1;
- break;
- }
-
- case PLCCommandAndQueryTypeEnum.SET_OBJECTIVE_AZEL_POSITION:
- {
- double NextAZ, NextEL;
-
- try
- {
- NextAZ = BitConverter.ToDouble(query, 3);
- NextEL = BitConverter.ToDouble(query, 11);
- }
- catch (Exception e)
- {
- if ((e is ArgumentException) || (e is ArgumentNullException) || (e is ArgumentOutOfRangeException))
- {
- // This error code means that the data could not be converted into a double-precision floating point
- FinalResponseContainer[2] = 0x2;
- break;
- }
- else
- {
- // Unexpected exception
- throw e;
- }
- }
-
- if ((NextAZ < 0) || (NextAZ > 360))
- {
- // This error code means that the objective azimuth position is invalid
- FinalResponseContainer[2] = 0x3;
- break;
- }
-
- if ((NextEL < 0) || (NextEL > 90))
- {
- // This error code means that the objective elevation position is invalid
- FinalResponseContainer[2] = 0x4;
- break;
- }
-
- // Otherwise, this is valid
- CurrentOrientation = new Orientation(NextAZ, NextEL);
-
- logger.Info("[TestPLCDriver] Setting current orientation to {" + CurrentOrientation.Azimuth.ToString() + ", " + CurrentOrientation.Elevation.ToString() + "}");
-
- FinalResponseContainer[2] = 0x1;
- break;
- }
-
- default:
- {
- throw new ArgumentException("Invalid PLCCommandAndQueryTypeEnum value seen while NOT expecting a response: " + CommandQueryTypeEnum.ToString());
- }
- }
- }
- else
- {
- throw new ArgumentException("Invalid PLCCommandResponseExpectationEnum value seen while processing client request in ScaleModelPLCDriver: " + ExpectedResponseStatusEnum.ToString());
- }
-
- return AttemptToWriteDataToServer(ActiveClientStream, FinalResponseContainer);
- }
-
- protected override void HandleClientManagementThread()
- {
- TcpClient AcceptedClient = null;
- byte[] StreamBuffer = new byte[256];
- byte[] ClippedData;
-
- while (!KillClientManagementThreadFlag)
- {
- if (PLCTCPListener.Pending())
- {
- AcceptedClient = PLCTCPListener.AcceptTcpClient();
- logger.Info("[AbstractPLCDriver] Connected to new client.");
-
- NetworkStream ClientStream = AcceptedClient.GetStream();
-
- int Fd;
- while ((!KillClientManagementThreadFlag) && (ClientStream != null))
- {
- if ((!ClientStream.CanRead) || (!ClientStream.DataAvailable))
- {
- continue;
- }
-
- Fd = ClientStream.Read(StreamBuffer, 0, StreamBuffer.Length);
-
- if (Fd == 0)
- {
- continue;
- }
-
- try
- {
- ClippedData = new byte[Fd];
- Array.Copy(StreamBuffer, ClippedData, ClippedData.Length);
-
- if (!ProcessRequest(ClientStream, ClippedData))
- {
- logger.Info("[AbstractPLCDriver] FAILED to write server.");
- }
- else
- {
- //logger.Info("[AbstractPLCDriver] Successfully wrote to server: [{0}]", string.Join(", ", ClippedData));
- //logger.Info("[AbstractPLCDriver] Successfully wrote to server!");
- }
- }
- catch (Exception e)
- {
- if ((e is ArgumentNullException)
- || (e is RankException)
- || (e is ArrayTypeMismatchException)
- || (e is InvalidCastException)
- || (e is ArgumentOutOfRangeException)
- || (e is ArgumentException))
- {
- logger.Info("[AbstractPLCDriver] ERROR: copying buffer array into clipped array {" + Fd + "}, skipping... [" + e.ToString());
- continue;
- }
- else
- {
- // Unexpected exception
- throw e;
- }
- }
- }
-
- ClientStream.Dispose();
- AcceptedClient.Dispose();
- }
- }
}
-
-
- protected bool AttemptToWriteDataToServer(NetworkStream ActiveClientStream, byte[] ResponseData)
- {
- try
- {
- ActiveClientStream.Write(ResponseData, 0, ResponseData.Length);
- }
- catch (Exception e)
- {
- if ((e is ArgumentNullException) || (e is ArgumentOutOfRangeException) || (e is System.IO.IOException) || (e is ObjectDisposedException))
- {
- logger.Info("[AbstractPLCDriver] ERROR: writing back to client with the PLC's response {" + ResponseData.ToString() + "}");
- return false;
- }
- }
-
- return true;
- }
-
-
}
}
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/PLCCommunication/PLCEvents.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/PLCCommunication/PLCEvents.cs
new file mode 100644
index 00000000..1f66baee
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/PLCCommunication/PLCEvents.cs
@@ -0,0 +1,128 @@
+using ControlRoomApplication.Entities;
+using ControlRoomApplication.Simulators.Hardware;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ControlRoomApplication.Controllers.PLCCommunication {
+
+ public class limitEventArgs {
+ public limitEventArgs( LimitSwitchData _AllLimits , PLC_modbus_server_register_mapping _ChangedValue , bool _Value ) { AllLimits = _AllLimits; ChangedValue = _ChangedValue; Value = _Value; }
+ public LimitSwitchData AllLimits { get; } // readonly
+ public PLC_modbus_server_register_mapping ChangedValue { get; } // readonly
+ public bool Value { get; } // readonly
+ }
+
+
+ public delegate void PLCLimitChangedEvent( object sender , limitEventArgs e );
+
+ ///
+ /// this class stores the static events used to signal Limitswitches and other events
+ ///
+ public class PLCEvents {
+ // Our static event
+ public static event PLCLimitChangedEvent LimitEvent;
+
+ private static PLCLimitChangedEvent defaultHandler;
+ private static List handles = new List();
+ private static object eventLock = new object();
+ private static bool overriden = false;
+
+ ///
+ /// set the default event handler for limit switch events, idealy this should only be called once
+ ///
+ ///
+ public static void setDefaultLimitHandler( PLCLimitChangedEvent _defa ) {
+ lock(eventLock) {
+ defaultHandler = _defa;
+ LimitEvent = defaultHandler;
+ }
+ }
+
+ ///
+ /// add a limit handle for limit events
+ ///
+ ///
+ public static void addLimitHandler( PLCLimitChangedEvent Handl ) {
+ lock(eventLock) {
+ if(!overriden) {
+ LimitEvent += Handl;
+ }
+ handles.Add( Handl );
+ }
+ }
+
+ ///
+ /// remove the passed event Handle
+ ///
+ ///
+ public static void RemoveLimitHandler( PLCLimitChangedEvent Handl ) {
+ lock(eventLock) {
+ try {
+ if(!overriden) {
+ LimitEvent -= Handl;
+ }
+ } catch { }
+ try {
+ handles.Remove( Handl );
+ } catch { }
+ }
+ }
+
+ ///
+ /// override all exsisting limit events and replace them with Handl
+ ///
+ ///
+ public static void OverrideLimitHandlers( PLCLimitChangedEvent Handl ) {
+ lock(eventLock) {
+ overriden = true;
+ LimitEvent = Handl;
+ }
+ }
+
+ public static void DurringOverrideAddSecondary( PLCLimitChangedEvent Handl ) {
+ lock(eventLock) {
+ LimitEvent += Handl;
+ handles.Add( Handl );
+ }
+ }
+
+ public static void DuringOverrideRemoveSecondary( PLCLimitChangedEvent Handl ) {
+ lock(eventLock) {
+ try {
+ LimitEvent -= Handl;
+ } catch { }
+ try {
+ handles.Remove( Handl );
+ } catch { }
+ }
+ }
+
+ ///
+ /// reset events to befor they were overriden
+ ///
+ public static void ResetOverrides() {
+ lock(eventLock) {
+ overriden = false;
+ LimitEvent = defaultHandler;
+ foreach(var evt in handles) {
+ LimitEvent += evt;
+ }
+ }
+ }
+
+ ///
+ /// call from the PLC driver when a switch value is changed, this should not be called elsewhere
+ ///
+ ///
+ ///
+ ///
+ public void PLCLimitChanged( LimitSwitchData _AllLimits , PLC_modbus_server_register_mapping _ChangedValue , bool _Value ) {
+ if(LimitEvent != null) {
+ LimitEvent( this , new limitEventArgs( _AllLimits , _ChangedValue , _Value ) );
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/RadioTelescopeController/RadioTelescopeController.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/RadioTelescopeController/RadioTelescopeController.cs
deleted file mode 100644
index 414b0109..00000000
--- a/ControlRoomApplication/ControlRoomApplication/Controllers/RadioTelescopeController/RadioTelescopeController.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-using ControlRoomApplication.Entities;
-
-namespace ControlRoomApplication.Controllers.RadioTelescopeController
-{
- public class RadioTelescopeController
- {
- public AbstractRadioTelescope RadioTelescope;
-
- public RadioTelescopeController(AbstractRadioTelescope radioTelescope)
- {
- RadioTelescope = radioTelescope;
- }
-
- public void GetCurrentRadioTelescopeRFData()
- {
- RadioTelescope.IntegrateNow();
- }
-
- public void StartRadioTelscopeRFDataScan()
- {
- RadioTelescope.StartContinuousIntegration();
- }
-
- public void StopRadioTelescopeRFDataScan()
- {
- RadioTelescope.StopContinuousIntegration();
- }
-
- public void ScheduleRadioTelescopeRFDataScan(int intervalMS, int delayMS = 0, bool startAfterDelay = false)
- {
- RadioTelescope.StartScheduledIntegration(intervalMS, delayMS, startAfterDelay);
- }
- }
-}
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/RadioTelescopeControllers/RadioTelescopeController.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/RadioTelescopeControllers/RadioTelescopeController.cs
index fa38e28a..266b7196 100644
--- a/ControlRoomApplication/ControlRoomApplication/Controllers/RadioTelescopeControllers/RadioTelescopeController.cs
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/RadioTelescopeControllers/RadioTelescopeController.cs
@@ -1,6 +1,17 @@
using System;
using System.Collections.Generic;
+using System.Threading.Tasks;
+using ControlRoomApplication.Constants;
using ControlRoomApplication.Entities;
+using System.Threading;
+using ControlRoomApplication.Controllers.Sensors;
+using ControlRoomApplication.Database;
+using ControlRoomApplication.Controllers.Communications;
+using ControlRoomApplication.Util;
+using System.Timers;
+using System.Diagnostics;
+using ControlRoomApplication.Controllers.PLCCommunication.PLCDrivers.MCUManager;
+using ControlRoomApplication.Controllers.PLCCommunication.PLCDrivers.MCUManager.Enumerations;
namespace ControlRoomApplication.Controllers
{
@@ -8,6 +19,33 @@ public class RadioTelescopeController
{
public RadioTelescope RadioTelescope { get; set; }
public CoordinateCalculationController CoordinateController { get; set; }
+ public OverrideSwitchData overrides;
+
+ ///
+ /// This is the final offset for when the telescope is set in production. It will be the offset to make sure
+ /// orientation 0,0 corresponds to what it should be when the telescope is set up.
+ ///
+ private Orientation FinalCalibrationOffset;
+
+ private object MovementLock = new object();
+
+ // Thread that monitors database current temperature
+ private Thread SensorMonitoringThread;
+ private bool MonitoringSensors;
+ private bool AllSensorsSafe;
+ public bool EnableSoftwareStops;
+
+ private double MaxElTempThreshold;
+ private double MaxAzTempThreshold;
+
+ // Previous snow dump azimuth -- we need to keep track of this in order to add 45 degrees each time we dump
+ private double previousSnowDumpAzimuth;
+
+ // Snow dump timer
+ private static System.Timers.Timer snowDumpTimer;
+
+ private static readonly log4net.ILog logger =
+ log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
///
/// Constructor that takes an AbstractRadioTelescope object and sets the
@@ -18,6 +56,27 @@ public RadioTelescopeController(RadioTelescope radioTelescope)
{
RadioTelescope = radioTelescope;
CoordinateController = new CoordinateCalculationController(radioTelescope.Location);
+
+ FinalCalibrationOffset = new Orientation(0, 0);
+
+ overrides = new OverrideSwitchData(radioTelescope);
+ radioTelescope.PLCDriver.Overrides = overrides;
+
+ SensorMonitoringThread = new Thread(SensorMonitor);
+ SensorMonitoringThread.Start();
+ MonitoringSensors = true;
+ AllSensorsSafe = true;
+ EnableSoftwareStops = true;
+
+ MaxAzTempThreshold = DatabaseOperations.GetThresholdForSensor(SensorItemEnum.AZ_MOTOR_TEMP);
+ MaxElTempThreshold = DatabaseOperations.GetThresholdForSensor(SensorItemEnum.ELEV_MOTOR_TEMP);
+
+ previousSnowDumpAzimuth = 0;
+
+ snowDumpTimer = new System.Timers.Timer(DatabaseOperations.FetchWeatherThreshold().SnowDumpTime * 1000 * 60);
+ snowDumpTimer.Elapsed += AutomaticSnowDumpInterval;
+ snowDumpTimer.AutoReset = true;
+ snowDumpTimer.Enabled = true;
}
///
@@ -30,10 +89,7 @@ public RadioTelescopeController(RadioTelescope radioTelescope)
/// Whether or not the RT responded.
public bool TestCommunication()
{
- return RadioTelescope.PLCDriver.Test_Conection();
-
- //byte[] ByteResponse = RadioTelescope.PLCClient.RequestMessageSend(PLCCommandAndQueryTypeEnum.TEST_CONNECTION);
- //return ResponseMetBasicExpectations(ByteResponse, 0x13) && (ByteResponse[3] == 0x1);
+ return RadioTelescope.PLCDriver.Test_Connection();
}
///
@@ -46,20 +102,18 @@ public bool TestCommunication()
/// An orientation object that holds the current azimuth/elevation of the scale model.
public Orientation GetCurrentOrientation()
{
+ // Apply final offset
+ Orientation finalOffsetOrientation = new Orientation();
- return RadioTelescope.PLCDriver.read_Position();
- /*
- byte[] ByteResponse = RadioTelescope.PLCClient.RequestMessageSend(PLCCommandAndQueryTypeEnum.GET_CURRENT_AZEL_POSITIONS);
- if (!ResponseMetBasicExpectations(ByteResponse, 0x13))
- {
- return null;
- }
-
- return new Orientation(BitConverter.ToDouble(ByteResponse, 3), BitConverter.ToDouble(ByteResponse, 11));
- //*/
- }
+ finalOffsetOrientation.Elevation = RadioTelescope.PLCDriver.GetMotorEncoderPosition().Elevation + FinalCalibrationOffset.Elevation;
+ finalOffsetOrientation.Azimuth = RadioTelescope.PLCDriver.GetMotorEncoderPosition().Azimuth + FinalCalibrationOffset.Azimuth;
+ // Normalize azimuth orientation
+ while (finalOffsetOrientation.Azimuth > 360) finalOffsetOrientation.Azimuth -= 360;
+ while (finalOffsetOrientation.Azimuth < 0) finalOffsetOrientation.Azimuth += 360;
+ return finalOffsetOrientation;
+ }
///
///
@@ -67,70 +121,17 @@ public Orientation GetCurrentOrientation()
///
public Orientation GetAbsoluteOrientation()
{
- return RadioTelescope.Encoders.GetCurentOrientation();
- }
+ // Apply final offset
+ Orientation finalOffsetOrientation = new Orientation();
+ finalOffsetOrientation.Elevation = RadioTelescope.SensorNetworkServer.CurrentAbsoluteOrientation.Elevation + FinalCalibrationOffset.Elevation;
+ finalOffsetOrientation.Azimuth = RadioTelescope.SensorNetworkServer.CurrentAbsoluteOrientation.Azimuth + FinalCalibrationOffset.Azimuth;
- ///
- /// Gets the current status of the four limit switches.
- ///
- /// The implementation of this functionality is on a "per-RT" basis, as
- /// in this may or may not work, it depends on if the derived
- /// AbstractRadioTelescope class has implemented it.
- ///
- ///
- /// An array of four booleans, where "true" means that the limit switch was triggered, and "false" means otherwise.
- /// The order of the limit switches are as follows:
- /// 0: Under limit azimuth
- /// 1: Under warning azimuth
- /// 2: Over warning azimuth
- /// 3: Over limit azimuth
- /// 4: Under limit elevation
- /// 5: Under warning elevation
- /// 6: Over warning elevation
- /// 7: Over limit elevation
- ///
- public bool[] GetCurrentLimitSwitchStatuses()
- {
- //throw new NotImplementedException();
- return RadioTelescope.PLCDriver.Get_Limit_switches();
-
- /*
- byte[] ByteResponse = RadioTelescope.PLCClient.RequestMessageSend(PLCCommandAndQueryTypeEnum.GET_CURRENT_LIMIT_SWITCH_STATUSES);
-
- if (!ResponseMetBasicExpectations(ByteResponse, 0x13))
- {
- return null;
- }
-
- bool[] Statuses = new bool[4];
+ // Normalize azimuth orientation
+ while (finalOffsetOrientation.Azimuth > 360) finalOffsetOrientation.Azimuth -= 360;
+ while (finalOffsetOrientation.Azimuth < 0) finalOffsetOrientation.Azimuth += 360;
- byte DataByte = ByteResponse[3];
- for (int i = 0; i < 4; i++)
- {
- switch (PLCLimitSwitchStatusConversionHelper.GetFromByte((byte)((DataByte >> (2 * (3 - i))) & 0x3)))
- {
- case PLCLimitSwitchStatusEnum.WITHIN_WARNING_LIMITS:
- {
- Statuses[i] = true;
- break;
- }
-
- case PLCLimitSwitchStatusEnum.WITHIN_SAFE_LIMITS:
- {
- Statuses[i] = false;
- break;
- }
-
- default:
- {
- throw new NotImplementedException("Unrecognized/Invalid response for byte-casted limit switch status.");
- }
- }
- }
-
- return Statuses;
- //*/
+ return finalOffsetOrientation;
}
///
@@ -144,8 +145,6 @@ public bool[] GetCurrentLimitSwitchStatuses()
public bool GetCurrentSafetyInterlockStatus()
{
return RadioTelescope.PLCDriver.Get_interlock_status();
- // byte[] ByteResponse = RadioTelescope.PLCClient.RequestMessageSend(PLCCommandAndQueryTypeEnum.GET_CURRENT_SAFETY_INTERLOCK_STATUS);
- //return ResponseMetBasicExpectations(ByteResponse, 0x13) && (ByteResponse[3] == 0x1);
}
///
@@ -155,10 +154,19 @@ public bool GetCurrentSafetyInterlockStatus()
/// in this may or may not work, it depends on if the derived
/// AbstractRadioTelescope class has implemented it.
///
- public bool CancelCurrentMoveCommand()
+ public MovementResult CancelCurrentMoveCommand(MovementPriority priority)
{
- return RadioTelescope.PLCDriver.Cancle_move();
- //return MinorResponseIsValid(RadioTelescope.PLCClient.RequestMessageSend(PLCCommandAndQueryTypeEnum.CANCEL_ACTIVE_OBJECTIVE_AZEL_POSITION));
+ MovementResult result = MovementResult.None;
+
+
+ if(Monitor.TryEnter(MovementLock) && priority > RadioTelescope.PLCDriver.CurrentMovementPriority)
+ {
+ result = RadioTelescope.PLCDriver.Cancel_move();
+ RadioTelescope.PLCDriver.CurrentMovementPriority = MovementPriority.None;
+ Monitor.Exit(MovementLock);
+ }
+
+ return result;
}
///
@@ -171,8 +179,11 @@ public bool CancelCurrentMoveCommand()
///
public bool ShutdownRadioTelescope()
{
- return RadioTelescope.PLCDriver.Shutdown_PLC_MCU();
- //return MinorResponseIsValid(RadioTelescope.PLCClient.RequestMessageSend(PLCCommandAndQueryTypeEnum.SHUTDOWN));
+ //MoveRadioTelescopeToOrientation(MiscellaneousConstants.Stow);
+ snowDumpTimer.Stop();
+ snowDumpTimer.Dispose();
+
+ return RadioTelescope.PLCDriver.RequestStopAsyncAcceptingClientsAndJoin();
}
///
@@ -182,37 +193,125 @@ public bool ShutdownRadioTelescope()
/// in this may or may not work, it depends on if the derived
/// AbstractRadioTelescope class has implemented it.
///
- public bool CalibrateRadioTelescope()
+ public MovementResult ThermalCalibrateRadioTelescope(MovementPriority priority)
{
- return RadioTelescope.PLCDriver.Calibrate();
- //return MinorResponseIsValid(RadioTelescope.PLCClient.RequestMessageSend(PLCCommandAndQueryTypeEnum.CALIBRATE));
+ MovementResult moveResult = MovementResult.None;
+
+ // Return if incoming priority is equal to or less than current movement
+ if (priority <= RadioTelescope.PLCDriver.CurrentMovementPriority) return MovementResult.AlreadyMoving;
+
+ // We only want to do this if it is safe to do so. Return false if not
+ if (!AllSensorsSafe) return MovementResult.SensorsNotSafe;
+
+ // If a lower-priority movement was running, safely interrupt it.
+ RadioTelescope.PLCDriver.InterruptMovementAndWaitUntilStopped();
+
+ // If the thread is locked (two moves coming in at the same time), return
+ if (Monitor.TryEnter(MovementLock))
+ {
+ Orientation current = GetCurrentOrientation();
+
+ RadioTelescope.PLCDriver.CurrentMovementPriority = priority;
+
+ moveResult = RadioTelescope.PLCDriver.MoveToOrientation(MiscellaneousConstants.THERMAL_CALIBRATION_ORIENTATION, current);
+
+ if (moveResult != MovementResult.Success)
+ {
+ if (RadioTelescope.PLCDriver.CurrentMovementPriority != MovementPriority.Critical) RadioTelescope.PLCDriver.CurrentMovementPriority = MovementPriority.None;
+ Monitor.Exit(MovementLock);
+ return moveResult;
+ }
+
+ // start a timer so we can have a time variable
+ Stopwatch stopWatch = new Stopwatch();
+ stopWatch.Start();
+
+ // temporarily set spectracyber mode to continuum
+ RadioTelescope.SpectraCyberController.SetSpectraCyberModeType(SpectraCyberModeTypeEnum.CONTINUUM);
+
+ // read data
+ SpectraCyberResponse response = RadioTelescope.SpectraCyberController.DoSpectraCyberScan();
+
+ // end the timer
+ stopWatch.Stop();
+ double time = stopWatch.Elapsed.TotalSeconds;
+
+ RFData rfResponse = RFData.GenerateFrom(response);
+
+ // move back to previous location
+ moveResult = RadioTelescope.PLCDriver.MoveToOrientation(current, MiscellaneousConstants.THERMAL_CALIBRATION_ORIENTATION);
+ if (moveResult != MovementResult.Success)
+ {
+ if (RadioTelescope.PLCDriver.CurrentMovementPriority != MovementPriority.Critical) RadioTelescope.PLCDriver.CurrentMovementPriority = MovementPriority.None;
+ RadioTelescope.SpectraCyberController.StopScan();
+ Monitor.Exit(MovementLock);
+ return moveResult;
+ }
+
+ // analyze data
+ // temperature (Kelvin) = (intensity * time * wein's displacement constant) / (Planck's constant * speed of light)
+ double weinConstant = 2.8977729;
+ double planckConstant = 6.62607004 * Math.Pow(10, -34);
+ double speedConstant = 299792458;
+ double temperature = (rfResponse.Intensity * time * weinConstant) / (planckConstant * speedConstant);
+
+ // convert to fahrenheit
+ temperature = temperature * (9 / 5) - 459.67;
+
+ // check against weather station reading
+ double weatherStationTemp = RadioTelescope.WeatherStation.GetOutsideTemp();
+
+ // Set SpectraCyber mode back to UNKNOWN
+ RadioTelescope.SpectraCyberController.SetSpectraCyberModeType(SpectraCyberModeTypeEnum.UNKNOWN);
+
+ // return true if working correctly, false if not
+ if (Math.Abs(weatherStationTemp - temperature) < MiscellaneousConstants.THERMAL_CALIBRATION_OFFSET)
+ {
+ moveResult = RadioTelescope.PLCDriver.MoveToOrientation(MiscellaneousConstants.Stow, current);
+ }
+
+ if (RadioTelescope.PLCDriver.CurrentMovementPriority != MovementPriority.Critical) RadioTelescope.PLCDriver.CurrentMovementPriority = MovementPriority.None;
+
+ RadioTelescope.SpectraCyberController.StopScan();
+ Monitor.Exit(MovementLock);
+ }
+ else
+ {
+ moveResult = MovementResult.AlreadyMoving;
+ }
+
+ return moveResult;
}
///
/// Method used to request to set configuration of elements of the RT.
- ///
- /// The implementation of this functionality is on a "per-RT" basis, as
- /// in this may or may not work, it depends on if the derived
- /// AbstractRadioTelescope class has implemented it.
+ /// takes the starting speed of the motor in RPM (speed of tellescope after gearing)
///
- public bool ConfigureRadioTelescope(int startSpeedAzimuth, int startSpeedElevation, int homeTimeoutAzimuth, int homeTimeoutElevation)
+ /// RPM
+ /// RPM
+ /// SEC
+ /// SEC
+ ///
+ public bool ConfigureRadioTelescope(double startSpeedAzimuth, double startSpeedElevation, int homeTimeoutAzimuth, int homeTimeoutElevation)
{
- return RadioTelescope.PLCDriver.Configure_MCU(startSpeedAzimuth, startSpeedElevation, homeTimeoutAzimuth, homeTimeoutElevation);
- /*
- if ((startSpeedAzimuth < 1) || (startSpeedElevation < 1) || (homeTimeoutAzimuth < 0) || (homeTimeoutElevation < 0)
- || (startSpeedAzimuth > 1000000) || (startSpeedElevation > 1000000) || (homeTimeoutAzimuth > 300) || (homeTimeoutElevation > 300))
- {
- return false;
- }
-
- return MinorResponseIsValid(RadioTelescope.PLCClient.RequestMessageSend(
- PLCCommandAndQueryTypeEnum.SET_CONFIGURATION,
- startSpeedAzimuth,
- startSpeedElevation,
- homeTimeoutAzimuth,
- homeTimeoutElevation
- ));
- //*/
+ return RadioTelescope.PLCDriver.Configure_MCU(startSpeedAzimuth, startSpeedElevation, homeTimeoutAzimuth, homeTimeoutElevation); // NO MOVE
+ }
+
+ ///
+ /// Gets the elevation readings used by the software stops. When the simulation sensor network is in use,
+ /// the motor positions are used, otherwise the sensor network's absolute orientation reading is used.
+ ///
+ /// ///
+ private double GetSoftwareStopElevation()
+ {
+ if (RadioTelescope.SensorNetworkServer.SimulationSensorNetwork != null)
+ {
+ return GetCurrentOrientation().Elevation;
+ }
+ else
+ {
+ return RadioTelescope.SensorNetworkServer.CurrentAbsoluteOrientation.Elevation;
+ }
}
///
@@ -223,10 +322,38 @@ public bool ConfigureRadioTelescope(int startSpeedAzimuth, int startSpeedElevati
/// in this may or may not work, it depends on if the derived
/// AbstractRadioTelescope class has implemented it.
///
- public bool MoveRadioTelescopeToOrientation(Orientation orientation)
+ public MovementResult MoveRadioTelescopeToOrientation(Orientation orientation, MovementPriority priority)
{
- return RadioTelescope.PLCDriver.Move_to_orientation(orientation, RadioTelescope.PLCDriver.read_Position());
- //return MinorResponseIsValid(RadioTelescope.PLCClient.RequestMessageSend(PLCCommandAndQueryTypeEnum.SET_OBJECTIVE_AZEL_POSITION, orientation));
+ MovementResult result = MovementResult.None;
+
+ if (EnableSoftwareStops && ((GetSoftwareStopElevation() > RadioTelescope.maxElevationDegrees && orientation.Elevation > RadioTelescope.maxElevationDegrees) ||
+ (GetSoftwareStopElevation() < RadioTelescope.minElevationDegrees && orientation.Elevation < RadioTelescope.minElevationDegrees))) return MovementResult.SoftwareStopHit;
+
+ // Return if incoming priority is equal to or less than current movement
+ if (priority <= RadioTelescope.PLCDriver.CurrentMovementPriority) return MovementResult.AlreadyMoving;
+
+ // We only want to do this if it is safe to do so. Return false if not
+ if (!AllSensorsSafe) return MovementResult.SensorsNotSafe;
+
+ // If a lower-priority movement was running, safely interrupt it.
+ RadioTelescope.PLCDriver.InterruptMovementAndWaitUntilStopped();
+
+ // If the thread is locked (two moves coming in at the same time), return
+ if (Monitor.TryEnter(MovementLock))
+ {
+ RadioTelescope.PLCDriver.CurrentMovementPriority = priority;
+
+ result = RadioTelescope.PLCDriver.MoveToOrientation(orientation, GetCurrentOrientation());
+ if (RadioTelescope.PLCDriver.CurrentMovementPriority == priority) RadioTelescope.PLCDriver.CurrentMovementPriority = MovementPriority.None;
+
+ Monitor.Exit(MovementLock);
+ }
+ else
+ {
+ result = MovementResult.AlreadyMoving;
+ }
+
+ return result;
}
///
@@ -237,77 +364,340 @@ public bool MoveRadioTelescopeToOrientation(Orientation orientation)
/// in this may or may not work, it depends on if the derived
/// AbstractRadioTelescope class has implemented it.
///
- public bool MoveRadioTelescopeToCoordinate(Coordinate coordinate)
+ public MovementResult MoveRadioTelescopeToCoordinate(Coordinate coordinate, MovementPriority priority)
{
- return MoveRadioTelescopeToOrientation(CoordinateController.CoordinateToOrientation(coordinate, DateTime.UtcNow));
+ MovementResult result = MovementResult.None;
+
+ Orientation orientation = CoordinateController.CoordinateToOrientation(coordinate, DateTime.UtcNow);
+
+ if (EnableSoftwareStops && (GetSoftwareStopElevation() > RadioTelescope.maxElevationDegrees && orientation.Elevation > RadioTelescope.maxElevationDegrees) ||
+ (GetSoftwareStopElevation() < RadioTelescope.minElevationDegrees && orientation.Elevation < RadioTelescope.minElevationDegrees)) return MovementResult.SoftwareStopHit;
+
+ // Return if incoming priority is equal to or less than current movement
+ if (priority <= RadioTelescope.PLCDriver.CurrentMovementPriority) return MovementResult.AlreadyMoving;
+
+ // We only want to do this if it is safe to do so. Return false if not
+ if (!AllSensorsSafe) return MovementResult.SensorsNotSafe;
+
+ // If a lower-priority movement was running, safely interrupt it.
+ RadioTelescope.PLCDriver.InterruptMovementAndWaitUntilStopped();
+
+ // If the thread is locked (two moves coming in at the same time), return
+ if (Monitor.TryEnter(MovementLock))
+ {
+ RadioTelescope.PLCDriver.CurrentMovementPriority = priority;
+
+ result = RadioTelescope.PLCDriver.MoveToOrientation(CoordinateController.CoordinateToOrientation(coordinate, DateTime.UtcNow), GetCurrentOrientation());
+ if (RadioTelescope.PLCDriver.CurrentMovementPriority == priority) RadioTelescope.PLCDriver.CurrentMovementPriority = MovementPriority.None;
+
+ Monitor.Exit(MovementLock);
+ }
+ else
+ {
+ result = MovementResult.AlreadyMoving;
+ }
+
+ return result;
}
///
- /// Method used to request to start jogging one of the Radio Telescope's axes
- /// at a speed, in either the clockwise or counter-clockwise direction.
- ///
- /// The implementation of this functionality is on a "per-RT" basis, as
- /// in this may or may not work, it depends on if the derived
- /// AbstractRadioTelescope class has implemented it.
+ /// This is a method used to move the radio telescope by X degrees.
+ /// Entering 0 for an axis will not move that motor.
///
- public bool StartRadioTelescopeJog(RadioTelescopeAxisEnum axis, int speed, bool clockwise)
+ /// The number of degrees to move by.
+ /// The movement's priority.
+ ///
+ public MovementResult MoveRadioTelescopeByXDegrees(Orientation degreesToMoveBy, MovementPriority priority)
{
- return RadioTelescope.PLCDriver.Start_jog(axis, speed, clockwise);
- //return MinorResponseIsValid(RadioTelescope.PLCClient.RequestMessageSend(PLCCommandAndQueryTypeEnum.START_JOG_MOVEMENT, axis, speed, clockwise));
+ MovementResult result = MovementResult.None;
+
+
+ // Return if incoming priority is equal to or less than current movement
+ if (priority <= RadioTelescope.PLCDriver.CurrentMovementPriority) return MovementResult.AlreadyMoving;
+
+ // We only want to do this if it is safe to do so. Return false if not
+ if (!AllSensorsSafe) return MovementResult.SensorsNotSafe;
+
+ if (Math.Abs(degreesToMoveBy.Azimuth) > MiscellaneousHardwareConstants.MOVE_BY_X_DEGREES_AZ_MAX) return MovementResult.RequestedAzimuthMoveTooLarge;
+
+ // If a lower-priority movement was running, safely interrupt it.
+ RadioTelescope.PLCDriver.InterruptMovementAndWaitUntilStopped();
+
+ Orientation origOrientation = GetCurrentOrientation();
+ double normalizedAzimuth = (degreesToMoveBy.Azimuth + origOrientation.Azimuth) % 360;
+ if(normalizedAzimuth < 0)
+ {
+ normalizedAzimuth += 360;
+ }
+
+ Orientation expectedOrientation = new Orientation(normalizedAzimuth, degreesToMoveBy.Elevation + origOrientation.Elevation);
+
+ if (expectedOrientation.Elevation < RadioTelescope.minElevationDegrees || expectedOrientation.Elevation > RadioTelescope.maxElevationDegrees) return MovementResult.InvalidRequestedPostion;
+
+ // If the thread is locked (two moves coming in at the same time), return
+ if (Monitor.TryEnter(MovementLock))
+ {
+ RadioTelescope.PLCDriver.CurrentMovementPriority = priority;
+
+
+ int absoluteElMove, absoluteAzMove;
+ absoluteElMove = ConversionHelper.DegreesToSteps(degreesToMoveBy.Elevation, MotorConstants.GEARING_RATIO_ELEVATION);
+ absoluteAzMove = ConversionHelper.DegreesToSteps(degreesToMoveBy.Azimuth, MotorConstants.GEARING_RATIO_AZIMUTH);
+
+ //Peak speed calculations (using 0.6 RPM to match other move functions)
+ int EL_Speed = ConversionHelper.DPSToSPS(ConversionHelper.RPMToDPS(0.6), MotorConstants.GEARING_RATIO_ELEVATION);
+ int AZ_Speed = ConversionHelper.DPSToSPS(ConversionHelper.RPMToDPS(0.6), MotorConstants.GEARING_RATIO_AZIMUTH);
+
+ result = RadioTelescope.PLCDriver.RelativeMove(AZ_Speed, EL_Speed, absoluteAzMove, absoluteElMove, expectedOrientation);
+
+ if (RadioTelescope.PLCDriver.CurrentMovementPriority == priority) RadioTelescope.PLCDriver.CurrentMovementPriority = MovementPriority.None;
+
+ Monitor.Exit(MovementLock);
+ }
+ else
+ {
+ result = MovementResult.AlreadyMoving;
+ }
+
+ return result;
+
}
///
- /// Method used to request to start jogging the Radio Telescope's azimuth
- /// at a speed, in either the clockwise or counter-clockwise direction.
- ///
- /// The implementation of this functionality is on a "per-RT" basis, as
- /// in this may or may not work, it depends on if the derived
- /// AbstractRadioTelescope class has implemented it.
+ /// This is used to home the telescope. Immediately after homing, the telescope will move to "Stow" position.
+ /// This will also zero out the absolute encoders and account for the true north offset.
///
- public bool StartRadioTelescopeAzimuthJog(int speed, bool clockwise)
+ /// The priority of this movement.
+ /// True if homing was successful; false if homing failed.
+ public MovementResult HomeTelescope(MovementPriority priority)
{
- return StartRadioTelescopeJog(RadioTelescopeAxisEnum.AZIMUTH, speed, clockwise);
+ MovementResult result = MovementResult.None;
+
+ // Return if incoming priority is equal to or less than current movement
+ if (priority <= RadioTelescope.PLCDriver.CurrentMovementPriority) return MovementResult.AlreadyMoving;
+
+ // We only want to do this if it is safe to do so. Return false if not
+ if (!AllSensorsSafe) return MovementResult.SensorsNotSafe;
+
+ // If a lower-priority movement was running, safely interrupt it.
+ RadioTelescope.PLCDriver.InterruptMovementAndWaitUntilStopped();
+
+ // If the thread is locked (two moves coming in at the same time), return
+ if (Monitor.TryEnter(MovementLock)) {
+ RadioTelescope.PLCDriver.CurrentMovementPriority = priority;
+
+ // Remove all offsets first so we can accurately zero out the positions
+ RadioTelescope.SensorNetworkServer.AbsoluteOrientationOffset = new Orientation(0, 0);
+ FinalCalibrationOffset = new Orientation(0, 0);
+ RadioTelescope.PLCDriver.SetFinalOffset(FinalCalibrationOffset);
+
+ EnableSoftwareStops = false;
+
+ // Perform a home telescope movement
+ result = RadioTelescope.PLCDriver.HomeTelescope();
+
+ EnableSoftwareStops = true;
+
+ // Zero out absolute encoders
+ RadioTelescope.SensorNetworkServer.AbsoluteOrientationOffset = (Orientation)RadioTelescope.SensorNetworkServer.CurrentAbsoluteOrientation.Clone();
+
+ // Allow the absolute encoders' positions to even out
+ Thread.Sleep(100);
+
+ // Verify the absolute encoders have successfully zeroed out. There is a bit of fluctuation with their values, so homing could have occurred
+ // with an outlier value. This check (with half-degree of precision) verifies that did not happen.
+ Orientation absOrientation = RadioTelescope.SensorNetworkServer.CurrentAbsoluteOrientation;
+ if ((Math.Abs(absOrientation.Elevation) > 0.5 && !overrides.overrideElevationAbsEncoder) ||
+ (Math.Abs(absOrientation.Azimuth) > 0.5 && !overrides.overrideAzimuthAbsEncoder))
+ {
+ result = MovementResult.IncorrectPosition;
+ }
+
+ // Apply final calibration offset
+ FinalCalibrationOffset = RadioTelescope.CalibrationOrientation;
+ RadioTelescope.PLCDriver.SetFinalOffset(FinalCalibrationOffset);
+
+ if (RadioTelescope.PLCDriver.CurrentMovementPriority == priority) RadioTelescope.PLCDriver.CurrentMovementPriority = MovementPriority.None;
+
+ Monitor.Exit(MovementLock);
+ }
+ else
+ {
+ result = MovementResult.AlreadyMoving;
+ }
+
+ return result;
+ }
+
+ ///
+ /// A demonstration script that moves the elevation motor to its maximum and minimum.
+ ///
+ /// Movement priority.
+ ///
+ public MovementResult FullElevationMove(MovementPriority priority)
+ {
+ MovementResult result = MovementResult.None;
+
+ // Return if incoming priority is equal to or less than current movement
+ if (priority <= RadioTelescope.PLCDriver.CurrentMovementPriority) return MovementResult.AlreadyMoving;
+
+ // We only want to do this if it is safe to do so. Return false if not
+ if (!AllSensorsSafe) return MovementResult.SensorsNotSafe;
+
+ // If a lower-priority movement was running, safely interrupt it.
+ RadioTelescope.PLCDriver.InterruptMovementAndWaitUntilStopped();
+
+ // If the thread is locked (two moves coming in at the same time), return
+ if (Monitor.TryEnter(MovementLock)) {
+ RadioTelescope.PLCDriver.CurrentMovementPriority = priority;
+
+ Orientation origOrientation = GetCurrentOrientation();
+
+ Orientation move1 = new Orientation(origOrientation.Azimuth, 0);
+ Orientation move2 = new Orientation(origOrientation.Azimuth, 90);
+
+ // Move to a low elevation point
+ result = RadioTelescope.PLCDriver.MoveToOrientation(move1, origOrientation);
+ if (result != MovementResult.Success)
+ {
+ if (RadioTelescope.PLCDriver.CurrentMovementPriority == priority) RadioTelescope.PLCDriver.CurrentMovementPriority = MovementPriority.None;
+ Monitor.Exit(MovementLock);
+ return result;
+ }
+
+ // Move to a high elevation point
+ result = RadioTelescope.PLCDriver.MoveToOrientation(move2, move1);
+ if (result != MovementResult.Success)
+ {
+ if (RadioTelescope.PLCDriver.CurrentMovementPriority == priority) RadioTelescope.PLCDriver.CurrentMovementPriority = MovementPriority.None;
+ Monitor.Exit(MovementLock);
+ return result;
+ }
+
+ // Move back to the original orientation
+ result = RadioTelescope.PLCDriver.MoveToOrientation(origOrientation, move2);
+
+ if (RadioTelescope.PLCDriver.CurrentMovementPriority == priority) RadioTelescope.PLCDriver.CurrentMovementPriority = MovementPriority.None;
+
+ Monitor.Exit(MovementLock);
+ }
+ else
+ {
+ result = MovementResult.AlreadyMoving;
+ }
+
+ return result;
}
///
/// Method used to request to start jogging the Radio Telescope's elevation
- /// at a speed, in either the clockwise or counter-clockwise direction.
- ///
- /// The implementation of this functionality is on a "per-RT" basis, as
- /// in this may or may not work, it depends on if the derived
- /// AbstractRadioTelescope class has implemented it.
+ /// at a speed (in RPM), in either the clockwise or counter-clockwise direction.
///
- public bool StartRadioTelescopeElevationJog(int speed, bool clockwise)
+ public MovementResult StartRadioTelescopeJog(double speed, RadioTelescopeDirectionEnum direction, RadioTelescopeAxisEnum axis)
{
- return StartRadioTelescopeJog(RadioTelescopeAxisEnum.ELEVATION, speed, clockwise);
+ MovementResult result = MovementResult.None;
+
+ //may want to check for jogs using the RadioTelescopeAxisEnum.BOTH if a jog on both axes is needed in the future
+ if (EnableSoftwareStops && axis == RadioTelescopeAxisEnum.ELEVATION)
+ {
+ if(direction == RadioTelescopeDirectionEnum.CounterclockwiseOrPositive && GetSoftwareStopElevation() > RadioTelescope.maxElevationDegrees)
+ {
+ return MovementResult.SoftwareStopHit;
+ }
+
+ else if(direction == RadioTelescopeDirectionEnum.ClockwiseOrNegative && GetSoftwareStopElevation() < RadioTelescope.minElevationDegrees)
+ {
+ return MovementResult.SoftwareStopHit;
+ }
+ }
+
+ // Return if incoming priority is equal to or less than current movement
+ if ((MovementPriority.Jog - 1) <= RadioTelescope.PLCDriver.CurrentMovementPriority) return MovementResult.AlreadyMoving;
+
+ // We only want to do this if it is safe to do so. Return false if not
+ if (!AllSensorsSafe) return MovementResult.SensorsNotSafe;
+
+ // If a lower-priority movement was running, safely interrupt it.
+ if (RadioTelescope.PLCDriver.InterruptMovementAndWaitUntilStopped())
+ {
+ return MovementResult.StoppingCurrentMove;
+ }
+
+ // If the thread is locked (two moves coming in at the same time), return
+ if (Monitor.TryEnter(MovementLock)) {
+ RadioTelescope.PLCDriver.CurrentMovementPriority = MovementPriority.Jog;
+
+ double azSpeed = 0;
+ double elSpeed = 0;
+
+ if (axis == RadioTelescopeAxisEnum.AZIMUTH) azSpeed = speed;
+ else elSpeed = speed;
+
+ result = RadioTelescope.PLCDriver.StartBothAxesJog(azSpeed, direction, elSpeed, direction);
+
+ Monitor.Exit(MovementLock);
+ }
+ else
+ {
+ result = MovementResult.AlreadyMoving;
+ }
+
+ return result;
}
+
///
- /// Method used to request that all of the Radio Telescope's movement comes
- /// to a controlled stop.
- ///
- /// The implementation of this functionality is on a "per-RT" basis, as
- /// in this may or may not work, it depends on if the derived
- /// AbstractRadioTelescope class has implemented it.
+ /// send a clear move to the MCU to stop a jog
///
- public bool ExecuteRadioTelescopeControlledStop()
+ public MovementResult ExecuteRadioTelescopeStopJog(MCUCommandType stopType)
{
- return RadioTelescope.PLCDriver.Controled_stop(RadioTelescopeAxisEnum.UNKNOWN, true);
- //return MinorResponseIsValid(RadioTelescope.PLCClient.RequestMessageSend(PLCCommandAndQueryTypeEnum.CONTROLLED_STOP));
+ MovementResult result = MovementResult.None;
+
+ if (RadioTelescope.PLCDriver.CurrentMovementPriority != MovementPriority.Jog) return result;
+
+ if (Monitor.TryEnter(MovementLock))
+ {
+ if (stopType == MCUCommandType.ControlledStop)
+ {
+ result = RadioTelescope.PLCDriver.Cancel_move();
+ }
+ else if (stopType == MCUCommandType.ImmediateStop)
+ {
+ result = RadioTelescope.PLCDriver.ImmediateStop();
+ }
+ else throw new ArgumentException("Jogs can only be stopped with a controlled stop or immediate stop.");
+
+ RadioTelescope.PLCDriver.CurrentMovementPriority = MovementPriority.None;
+
+ Monitor.Exit(MovementLock);
+ }
+
+ return result;
}
///
/// Method used to request that all of the Radio Telescope's movement comes
- /// to an immediate stop.
+ /// to a controlled stop. this will not work for jog moves use
///
/// The implementation of this functionality is on a "per-RT" basis, as
/// in this may or may not work, it depends on if the derived
/// AbstractRadioTelescope class has implemented it.
///
- public bool ExecuteRadioTelescopeImmediateStop()
+ public MovementResult ExecuteRadioTelescopeControlledStop(MovementPriority priority)
{
- return RadioTelescope.PLCDriver.Immediade_stop();
- //return MinorResponseIsValid(RadioTelescope.PLCClient.RequestMessageSend(PLCCommandAndQueryTypeEnum.IMMEDIATE_STOP));
+ MovementResult result = MovementResult.None;
+
+ if (Monitor.TryEnter(MovementLock))
+ {
+ if (priority > RadioTelescope.PLCDriver.CurrentMovementPriority)
+ {
+ result = RadioTelescope.PLCDriver.ControlledStop();
+ RadioTelescope.PLCDriver.CurrentMovementPriority = MovementPriority.None;
+ }
+ Monitor.Exit(MovementLock);
+ }
+
+ return result;
}
///
@@ -318,69 +708,413 @@ public bool ExecuteRadioTelescopeImmediateStop()
/// in this may or may not work, it depends on if the derived
/// AbstractRadioTelescope class has implemented it.
///
- public bool ExecuteMoveRelativeAzimuth(RadioTelescopeAxisEnum axis, int speed, int position)
+ public MovementResult ExecuteRadioTelescopeImmediateStop(MovementPriority priority)
{
- int positionTranslationAZ=0, positionTranslationEL=0;
- if (axis == RadioTelescopeAxisEnum.ELEVATION)
+ MovementResult result = MovementResult.None;
+
+ if (Monitor.TryEnter(MovementLock))
{
- positionTranslationEL = position;
+ if (priority > RadioTelescope.PLCDriver.CurrentMovementPriority)
+ {
+ result = RadioTelescope.PLCDriver.ImmediateStop();
+ RadioTelescope.PLCDriver.CurrentMovementPriority = MovementPriority.None;
+ }
+ Monitor.Exit(MovementLock);
}
- else if (axis == RadioTelescopeAxisEnum.AZIMUTH)
+
+ return result;
+ }
+
+ ///
+ /// This allows us to safely reset the motor controller errors if an error bit happens to be set.
+ /// This way, we don't have to restart the hardware to get things to work.
+ ///
+ ///
+ /// This will overwrite a movement if one is currently running, so it cannot be run unless there are
+ /// no movements running.
+ ///
+ /// True if successful, False if another movement is currently running
+ public bool ResetMCUErrors()
+ {
+ bool success = false;
+
+ if(Monitor.TryEnter(MovementLock))
{
- positionTranslationAZ = position;
+ RadioTelescope.PLCDriver.ResetMCUErrors();
+ success = true;
+ Monitor.Exit(MovementLock);
}
- else return false;
- return RadioTelescope.PLCDriver.relative_move(speed, (ushort) 50, positionTranslationAZ, positionTranslationEL);
- //return MinorResponseIsValid(RadioTelescope.PLCClient.RequestMessageSend(PLCCommandAndQueryTypeEnum.TRANSLATE_AZEL_POSITION, axis, speed, position));
+ return success;
}
+
///
/// return true if the RT has finished the previous move comand
///
- public bool finished_exicuting_move()
+ public bool finished_exicuting_move( RadioTelescopeAxisEnum axis )//[7]
+ {
+
+ var Taz = RadioTelescope.PLCDriver.GET_MCU_Status( RadioTelescopeAxisEnum.AZIMUTH );
+ var Tel = RadioTelescope.PLCDriver.GET_MCU_Status( RadioTelescopeAxisEnum.ELEVATION );
+
+ bool azFin = Taz[(int)MCUConstants.MCUStatusBitsMSW.Move_Complete];
+ bool elFin = Tel[(int)MCUConstants.MCUStatusBitsMSW.Move_Complete];
+ if(axis == RadioTelescopeAxisEnum.BOTH) {
+ return elFin && azFin;
+ } else if(axis == RadioTelescopeAxisEnum.AZIMUTH) {
+ return azFin;
+ } else if(axis == RadioTelescopeAxisEnum.ELEVATION) {
+ return elFin;
+ }
+ return false;
+ }
+
+ // Checks the motor temperatures against acceptable ranges every second
+ private void SensorMonitor()
+ {
+ // Getting initial current temperatures
+ Temperature currAzTemp = RadioTelescope.SensorNetworkServer.CurrentAzimuthMotorTemp[RadioTelescope.SensorNetworkServer.CurrentAzimuthMotorTemp.Length - 1];
+ Temperature currElTemp = RadioTelescope.SensorNetworkServer.CurrentElevationMotorTemp[RadioTelescope.SensorNetworkServer.CurrentElevationMotorTemp.Length - 1];
+ bool elTempSafe = checkTemp(currElTemp, true);
+ bool azTempSafe = checkTemp(currAzTemp, true);
+
+ // Sensor overrides must be taken into account
+ bool currentAZOveride = overrides.overrideAzimuthMotTemp;
+ bool currentELOveride = overrides.overrideElevatMotTemp;
+
+ // Loop through every one second to get new sensor data
+ while (MonitoringSensors)
+ {
+ Temperature azTemp = RadioTelescope.SensorNetworkServer.CurrentAzimuthMotorTemp[RadioTelescope.SensorNetworkServer.CurrentAzimuthMotorTemp.Length - 1];
+ Temperature elTemp = RadioTelescope.SensorNetworkServer.CurrentElevationMotorTemp[RadioTelescope.SensorNetworkServer.CurrentElevationMotorTemp.Length - 1];
+
+ azTempSafe = checkTemp(azTemp, azTempSafe);
+ elTempSafe = checkTemp(elTemp, elTempSafe);
+
+ // Determines if the telescope is in a safe state
+ if (azTempSafe && elTempSafe) AllSensorsSafe = true;
+ else
+ {
+ AllSensorsSafe = false;
+
+ // If the motors are moving, interrupt the current movement.
+ if (RadioTelescope.PLCDriver.MotorsCurrentlyMoving())
+ {
+ RadioTelescope.PLCDriver.InterruptMovementAndWaitUntilStopped();
+ }
+ }
+
+ // Run the software-stop routine
+ CheckAndRunSoftwareStops();
+
+ Thread.Sleep(100);
+ }
+ }
+
+ ///
+ /// Checks that the motor temperatures are within acceptable ranges. If the temperature exceeds
+ /// the corresponding value in SimulationConstants.cs, it will return false, otherwise
+ /// it will return true if everything is good.
+ /// Tl;dr:
+ /// False - bad
+ /// True - good
+ ///
+ /// override bool
+ public bool checkTemp(Temperature t, bool lastIsSafe)
{
- bool[] flags =RadioTelescope.PLCDriver.GET_MCU_Status();
- /*/Console.Write("\n");
- foreach (bool flag in flags)
+ // get maximum temperature threshold
+ double max;
+
+ // Determine whether azimuth or elevation
+ String s;
+ bool isOverridden;
+ if (t.location_ID == (int)SensorLocationEnum.AZ_MOTOR)
+ {
+ s = "Azimuth";
+ isOverridden = overrides.overrideAzimuthMotTemp;
+ max = MaxAzTempThreshold;
+ }
+ else
+ {
+ s = "Elevation";
+ isOverridden = overrides.overrideElevatMotTemp;
+ max = MaxElTempThreshold;
+ }
+
+ // Check temperatures
+ if (t.temp < SimulationConstants.MIN_MOTOR_TEMP)
{
- Console.Write(" " + flag + ",");
+ if (lastIsSafe)
+ {
+ logger.Info(Utilities.GetTimeStamp() + ": " + s + " motor temperature BELOW stable temperature by " + Math.Truncate(SimulationConstants.STABLE_MOTOR_TEMP - t.temp) + " degrees Fahrenheit.");
+
+ pushNotification.sendToAllAdmins("MOTOR TEMPERATURE", s + " motor temperature BELOW stable temperature by " + Math.Truncate(SimulationConstants.STABLE_MOTOR_TEMP - t.temp) + " degrees Fahrenheit.");
+ EmailNotifications.sendToAllAdmins("MOTOR TEMPERATURE", s + " motor temperature BELOW stable temperature by " + Math.Truncate(SimulationConstants.STABLE_MOTOR_TEMP - t.temp) + " degrees Fahrenheit.");
+ }
+
+ // Only overrides if switch is true
+ if (!isOverridden) return false;
+ else return true;
}
- Console.Write("\n");//*/
- return flags[7];
+ else if (t.temp > SimulationConstants.OVERHEAT_MOTOR_TEMP)
+ {
+ if (lastIsSafe)
+ {
+ logger.Info(Utilities.GetTimeStamp() + ": " + s + " motor temperature OVERHEATING by " + Math.Truncate(t.temp - max) + " degrees Fahrenheit.");
+
+ pushNotification.sendToAllAdmins("MOTOR TEMPERATURE", s + " motor temperature OVERHEATING by " + Math.Truncate(t.temp - max) + " degrees Fahrenheit.");
+ EmailNotifications.sendToAllAdmins("MOTOR TEMPERATURE", s + " motor temperature OVERHEATING by " + Math.Truncate(t.temp - max) + " degrees Fahrenheit.");
+ }
+
+ // Only overrides if switch is true
+ if (!isOverridden) return false;
+ else return true;
+ }
+ else if (t.temp <= SimulationConstants.MAX_MOTOR_TEMP && t.temp >= SimulationConstants.MIN_MOTOR_TEMP && !lastIsSafe) {
+ logger.Info(Utilities.GetTimeStamp() + ": " + s + " motor temperature stable.");
+
+ pushNotification.sendToAllAdmins("MOTOR TEMPERATURE", s + " motor temperature stable.");
+ EmailNotifications.sendToAllAdmins("MOTOR TEMPERATURE", s + " motor temperature stable.");
+ }
+
+ return true;
}
+ ///
+ /// This will set the overrides based on input. Takes in the sensor that it will be changing,
+ /// and then the status, true or false.
+ /// true = overriding
+ /// false = enabled
+ ///
+ ///
+ ///
+ public void setOverride(String sensor, bool set)
+ {
+ if (sensor.Equals("azimuth motor temperature")) overrides.setAzimuthMotTemp(set);
+ else if (sensor.Equals("elevation motor temperature")) overrides.setElevationMotTemp(set);
+ else if (sensor.Equals("main gate")) overrides.setGatesOverride(set);
+ else if (sensor.Equals("elevation proximity (1)")) overrides.setElProx0Override(set);
+ else if (sensor.Equals("elevation proximity (2)")) overrides.setElProx90Override(set);
+ else if (sensor.Equals("azimuth absolute encoder")) overrides.setAzimuthAbsEncoder(set);
+ else if (sensor.Equals("elevation absolute encoder")) overrides.setElevationAbsEncoder(set);
+ else if (sensor.Equals("azimuth motor accelerometer")) overrides.setAzimuthAccelerometer(set);
+ else if (sensor.Equals("elevation motor accelerometer")) overrides.setElevationAccelerometer(set);
+ else if (sensor.Equals("counterbalance accelerometer")) overrides.setCounterbalanceAccelerometer(set);
- private static bool ResponseMetBasicExpectations(byte[] ResponseBytes, int ExpectedSize)
+
+ if (set)
+ {
+ logger.Info(Utilities.GetTimeStamp() + ": Overriding " + sensor + " sensor.");
+
+ pushNotification.sendToAllAdmins("SENSOR OVERRIDES", "Overriding " + sensor + " sensor.");
+ EmailNotifications.sendToAllAdmins("SENSOR OVERRIDES", "Overriding " + sensor + " sensor.");
+ }
+ else
+ {
+ logger.Info(Utilities.GetTimeStamp() + ": Enabled " + sensor + " sensor.");
+
+ pushNotification.sendToAllAdmins("SENSOR OVERRIDES", "Enabled " + sensor + " sensor.");
+ EmailNotifications.sendToAllAdmins("SENSOR OVERRIDES", "Enabled " + sensor + " sensor.");
+ }
+ }
+
+ ///
+ /// This is a script that is called when we want to dump snow out of the dish
+ ///
+ public MovementResult SnowDump(MovementPriority priority)
{
- return ((ResponseBytes[0] + (ResponseBytes[1] * 256)) == ExpectedSize) && (ResponseBytes[2] == 0x1);
- //TODO: throws object is not instance of object when the PLCClientCommunicationHandler.ReadResponse() retuns null usually due to time out
+ MovementResult result = MovementResult.None;
- }
+ // Return if incoming priority is equal to or less than current movement
+ if (priority <= RadioTelescope.PLCDriver.CurrentMovementPriority) return MovementResult.AlreadyMoving;
- private static bool MinorResponseIsValid(byte[] MinorResponseBytes)
+ // We only want to do this if it is safe to do so. Return false if not
+ if (!AllSensorsSafe) return MovementResult.SensorsNotSafe;
+
+ // If a lower-priority movement was running, safely interrupt it.
+ RadioTelescope.PLCDriver.InterruptMovementAndWaitUntilStopped();
+
+ // If the thread is locked (two moves coming in at the same time), return
+ if (Monitor.TryEnter(MovementLock)) {
+
+ RadioTelescope.PLCDriver.CurrentMovementPriority = priority;
+
+
+ // insert snow dump movements here
+ // default is azimuth of 0 and elevation of 0
+ previousSnowDumpAzimuth += 45;
+ if (previousSnowDumpAzimuth >= 360) previousSnowDumpAzimuth -= 360;
+
+ Orientation dump = new Orientation(previousSnowDumpAzimuth, -4);
+ Orientation current = GetCurrentOrientation();
+
+ Orientation dumpAzimuth = new Orientation(dump.Azimuth, current.Elevation);
+ Orientation dumpElevation = new Orientation(dump.Azimuth, dump.Elevation);
+
+ // move to dump snow
+ result = RadioTelescope.PLCDriver.MoveToOrientation(dumpAzimuth, current);
+ if (result != MovementResult.Success)
+ {
+ if (RadioTelescope.PLCDriver.CurrentMovementPriority == priority) RadioTelescope.PLCDriver.CurrentMovementPriority = MovementPriority.None;
+ Monitor.Exit(MovementLock);
+ return result;
+ }
+
+ result = RadioTelescope.PLCDriver.MoveToOrientation(dumpElevation, dumpAzimuth);
+ if (result != MovementResult.Success)
+ {
+ if (RadioTelescope.PLCDriver.CurrentMovementPriority == priority) RadioTelescope.PLCDriver.CurrentMovementPriority = MovementPriority.None;
+ Monitor.Exit(MovementLock);
+ return result;
+ }
+
+ // move back to initial orientation
+ result = RadioTelescope.PLCDriver.MoveToOrientation(current, dumpElevation);
+
+ if (RadioTelescope.PLCDriver.CurrentMovementPriority == priority) RadioTelescope.PLCDriver.CurrentMovementPriority = MovementPriority.None;
+
+ Monitor.Exit(MovementLock);
+ }
+ else
+ {
+ result = MovementResult.AlreadyMoving;
+ }
+
+ return result;
+ }
+
+ private void AutomaticSnowDumpInterval(Object source, ElapsedEventArgs e)
{
+ double DELTA = 0.01;
+ Orientation currentOrientation = GetCurrentOrientation();
- System.Diagnostics.Debug.WriteLine(MinorResponseBytes);
- return ResponseMetBasicExpectations(MinorResponseBytes, 0x3);
+ // Check if we need to dump the snow off of the telescope
+ if (RadioTelescope.WeatherStation.GetOutsideTemp() <= 30.00 && RadioTelescope.WeatherStation.GetTotalRain() > 0.00)
+ {
+ // We want to check stow position precision with a 0.01 degree margin of error
+ if(Math.Abs(currentOrientation.Azimuth - MiscellaneousConstants.Stow.Azimuth) <= DELTA && Math.Abs(currentOrientation.Elevation - MiscellaneousConstants.Stow.Elevation) <= DELTA)
+ {
+ Console.WriteLine("Time threshold reached. Running snow dump...");
+
+ MovementResult result = SnowDump(MovementPriority.Appointment);
+
+ if(result != MovementResult.Success)
+ {
+ logger.Info($"{Utilities.GetTimeStamp()}: Automatic snow dump FAILED with error message: {result.ToString()}");
+ pushNotification.sendToAllAdmins("Snow Dump Failed", $"Automatic snow dump FAILED with error message: {result.ToString()}");
+ EmailNotifications.sendToAllAdmins("Snow Dump Failed", $"Automatic snow dump FAILED with error message: {result.ToString()}");
+ }
+ else
+ {
+ Console.WriteLine("Snow dump completed");
+ }
+ }
+
+ }
}
- private static RFData GenerateRFData(SpectraCyberResponse spectraCyberResponse)
+ ///
+ /// This method runs the hardware movement script, used to verify the telescopes full ROM (az and el) and confirm that we can
+ /// safely back off from both limit switches.
+ ///
+ ///
+ ///
+ public MovementResult ExecuteHardwareMovementScript(MovementPriority priority)
{
- RFData rfData = new RFData();
- rfData.TimeCaptured = spectraCyberResponse.DateTimeCaptured;
- rfData.Intensity = spectraCyberResponse.DecimalData;
- return rfData;
+ MovementResult movementResult = MovementResult.None;
+
+ // Return if incoming priority is equal to or less than current movement
+ if (priority <= RadioTelescope.PLCDriver.CurrentMovementPriority) return MovementResult.AlreadyMoving;
+
+ // We only want to do this if it is safe to do so. Return false if not
+ if (!AllSensorsSafe) return MovementResult.SensorsNotSafe;
+
+ // If a lower-priority movement was running, safely interrupt it.
+ RadioTelescope.PLCDriver.InterruptMovementAndWaitUntilStopped();
+
+ // If the thread is locked (two moves coming in at the same time), return
+ if (Monitor.TryEnter(MovementLock))
+ {
+ // First, home telescope to get correct positioning
+ logger.Info($"{Utilities.GetTimeStamp()}: Beginning first movement: Home Telescope...");
+ movementResult = HomeTelescope(MovementPriority.Manual);
+
+ logger.Info($"{Utilities.GetTimeStamp()}: Finished first movement: Home Telescope, waiting 1 second before beginning next movement...");
+ Thread.Sleep(1000);
+
+
+ // TEST 1: Move to Azimuth 180 degrees
+ logger.Info($"{Utilities.GetTimeStamp()}: Beginning second movement: Move Azimuth by 180 degrees...");
+ Entities.Orientation currOrientation = GetCurrentOrientation();
+ movementResult = MoveRadioTelescopeToOrientation(new Entities.Orientation(180, currOrientation.Elevation), MovementPriority.Manual);
+ logger.Info($"{Utilities.GetTimeStamp()}: Finished second movement: Move Azimuth by 180 degrees, waiting 1 second before beginning next movement...");
+ Thread.Sleep(1000);
+
+ //TEST 2: Move in opposite direction 180 degrees using orientation from 180 degrees in opposite direction
+ logger.Info($"{Utilities.GetTimeStamp()}: Beginning third movement: Move Azimuth by -180 degrees...");
+ movementResult = MoveRadioTelescopeToOrientation(currOrientation, MovementPriority.Manual);
+ logger.Info($"{Utilities.GetTimeStamp()}: Finished third movement: Move Azimuth by -180 degrees, waiting 1 second before beginning next movement...");
+ Thread.Sleep(1000);
+
+ // TEST 3: Move to 90 degrees elevation
+ logger.Info($"{Utilities.GetTimeStamp()}: Beginning fourth movement: Move Elevation to 90 degrees");
+ movementResult = MoveRadioTelescopeToOrientation(new Entities.Orientation(currOrientation.Azimuth, 90), MovementPriority.Manual);
+ logger.Info($"{Utilities.GetTimeStamp()}: Finished fourth movement: Move Elevation to 90 degrees, waiting 1 second before beginning next movement...");
+ Thread.Sleep(1000);
+
+ //TEST 4: Move to 0 degrees elevation
+ logger.Info($"{Utilities.GetTimeStamp()}: Beginning fifth movement: Move Elevation to 0 degrees");
+ movementResult = MoveRadioTelescopeToOrientation(new Entities.Orientation(currOrientation.Azimuth, 0), MovementPriority.Manual);
+ logger.Info($"{Utilities.GetTimeStamp()}: Finished fifth movement: Move Elevation to 0 degrees, waiting 1 second before beginning next movement...");
+ Thread.Sleep(1000);
+
+ // TEST 5: Move to lower elevation limit switch - movement should fail
+ logger.Info($"{Utilities.GetTimeStamp()}: Beginning sixth movement: Move Elevation to -8 degrees (lower limit switch)");
+ movementResult = MoveRadioTelescopeToOrientation(new Entities.Orientation(currOrientation.Azimuth, -8), MovementPriority.Manual);
+ logger.Info($"{Utilities.GetTimeStamp()}: Finished sixth movement: Move Elevation to -8 degrees, waiting 5 seconds before beginning next movement...");
+ Thread.Sleep(5000);
+
+ // TEST 6: Move to upper elevation limit switch - movement should fail
+ logger.Info($"{Utilities.GetTimeStamp()}: Beginning seventh movement: Move Elevation to 95 degrees (upper limit switch)");
+ movementResult = MoveRadioTelescopeToOrientation(new Entities.Orientation(currOrientation.Azimuth, 95), MovementPriority.Manual);
+ logger.Info($"{Utilities.GetTimeStamp()}: Finished seventh movement: Move Elevation to 95 degrees, waiting 1 second before beginning next movement...");
+ Thread.Sleep(5000);
+
+ //TEST 7: Return to home
+ logger.Info($"{Utilities.GetTimeStamp()}: Beginning eigth movement: Move to Home");
+ movementResult = HomeTelescope(MovementPriority.Manual);
+ logger.Info($"{Utilities.GetTimeStamp()}: Finished eigth movement: Move to home");
+ Thread.Sleep(1000);
+
+ Monitor.Exit(MovementLock);
+ }
+ else
+ {
+ movementResult = MovementResult.AlreadyMoving;
+ }
+
+ return movementResult;
}
- private static List GenerateRFDataList(List spectraCyberResponses)
+ ///
+ /// This is the method that handles and executes the software-stop logic
+ ///
+ private void CheckAndRunSoftwareStops()
{
- List rfDataList = new List();
- foreach (SpectraCyberResponse response in spectraCyberResponses)
+ // Run checks for software-stops only if they are enabled
+ if (EnableSoftwareStops)
{
- rfDataList.Add(GenerateRFData(response));
- }
+ // Get the elevation direction
+ RadioTelescopeDirectionEnum direction = RadioTelescope.PLCDriver.GetRadioTelescopeDirectionEnum(RadioTelescopeAxisEnum.ELEVATION);
- return rfDataList;
+ // Perform a critical movement interrupt if the telescope is moving past either elevation threshold
+ if ((GetSoftwareStopElevation() > RadioTelescope.maxElevationDegrees && direction == RadioTelescopeDirectionEnum.CounterclockwiseOrPositive) ||
+ (GetSoftwareStopElevation() < RadioTelescope.minElevationDegrees && direction == RadioTelescopeDirectionEnum.ClockwiseOrNegative))
+ {
+ RadioTelescope.PLCDriver.InterruptMovementAndWaitUntilStopped(true, true);
+ logger.Info(Utilities.GetTimeStamp() + ": Software-stop hit!");
+ }
+ }
}
}
}
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Enumerations/AccelerometerErrorCodes.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Enumerations/AccelerometerErrorCodes.cs
new file mode 100644
index 00000000..37351f2f
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Enumerations/AccelerometerErrorCodes.cs
@@ -0,0 +1,29 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ControlRoomApplication.Controllers.SensorNetwork.Enumerations
+{
+ ///
+ /// Denotes what the error state of an accelerometer is in.
+ ///
+ public enum AccelerometerErrorCodes
+ {
+ ///
+ /// The sensor is working properly.
+ ///
+ NoError,
+
+ ///
+ /// The sensor stopped sampling.
+ ///
+ NoSamples,
+
+ ///
+ /// The waterfall interrupt was missed.
+ ///
+ WaterfallMissed
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Enumerations/AccelerometerSelfTestState.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Enumerations/AccelerometerSelfTestState.cs
new file mode 100644
index 00000000..c32b18ed
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Enumerations/AccelerometerSelfTestState.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ControlRoomApplication.Controllers.SensorNetwork.Enumerations
+{
+ ///
+ /// Denotes whether or not an accelerometer's self test failed or passed.
+ ///
+ public enum AccelerometerSelfTestState
+ {
+ ///
+ /// The self test failed.
+ ///
+ Error,
+
+ ///
+ /// The self test succeeded.
+ ///
+ Okay
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Enumerations/AzimuthEncoderErrorCodes.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Enumerations/AzimuthEncoderErrorCodes.cs
new file mode 100644
index 00000000..15f84783
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Enumerations/AzimuthEncoderErrorCodes.cs
@@ -0,0 +1,29 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ControlRoomApplication.Controllers.SensorNetwork.Enumerations
+{
+ ///
+ /// Denotes the error state of the azimuth absolute encoder.
+ ///
+ public enum AzimuthEncoderErrorCodes
+ {
+ ///
+ /// The sensor is working properly.
+ ///
+ NoError,
+
+ ///
+ /// Valid flag returned false.
+ ///
+ BadData,
+
+ ///
+ /// Sync flag returned false.
+ ///
+ StaleData
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Enumerations/SensorInitializationEnum.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Enumerations/SensorInitializationEnum.cs
new file mode 100644
index 00000000..e27af879
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Enumerations/SensorInitializationEnum.cs
@@ -0,0 +1,57 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ControlRoomApplication.Controllers.SensorNetwork
+{
+ ///
+ /// Contains sensor initialization that is used to determine what sensor is at what index
+ /// in the byte array
+ ///
+ public enum SensorInitializationEnum
+ {
+ ///
+ /// Elevation temperature initialization. This corresponds to the index of this sensor in the
+ /// sensor initialization byte array.
+ ///
+ ElevationTemp,
+
+ ///
+ /// Azimuth temperature initialization. This corresponds to the index of this sensor in the
+ /// sensor initialization byte array.
+ ///
+ AzimuthTemp,
+
+ ///
+ /// Elevation encoder initialization. This corresponds to the index of this sensor in the
+ /// sensor initialization byte array.
+ ///
+ ElevationEncoder,
+
+ ///
+ /// Azimuth encoder initialization. This corresponds to the index of this sensor in the
+ /// sensor initialization byte array.
+ ///
+ AzimuthEncoder,
+
+ ///
+ /// Azimuth accelerometer initialization. This corresponds to the index of this sensor in the
+ /// sensor initialization byte array.
+ ///
+ AzimuthAccelerometer,
+
+ ///
+ /// Elevation accelerometer initialization. This corresponds to the index of this sensor in the
+ /// sensor initialization byte array.
+ ///
+ ElevationAccelerometer,
+
+ ///
+ /// Counterbalance accelerometer initialization. This corresponds to the index of this sensor in the
+ /// sensor initialization byte array.
+ ///
+ CounterbalanceAccelerometer
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Enumerations/SensorNetworkSensorStatus.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Enumerations/SensorNetworkSensorStatus.cs
new file mode 100644
index 00000000..2bc147c8
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Enumerations/SensorNetworkSensorStatus.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ControlRoomApplication.Entities.DiagnosticData
+{
+ ///
+ /// Denotes whether or not a sensor is in error.
+ ///
+ public enum SensorNetworkSensorStatus
+ {
+ ///
+ /// The sensor is in error.
+ ///
+ Error,
+
+ ///
+ /// The sensor is working properly.
+ ///
+ Okay
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Enumerations/SensorNetworkStatusEnum.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Enumerations/SensorNetworkStatusEnum.cs
new file mode 100644
index 00000000..af885c92
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Enumerations/SensorNetworkStatusEnum.cs
@@ -0,0 +1,76 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ControlRoomApplication.Controllers.SensorNetwork
+{
+ ///
+ /// This enum will tell you what status the Sensor Network is in. This can change depending on
+ /// whether it just started, or if it receives any error codes from the Sensor Network itself.
+ ///
+ public enum SensorNetworkStatusEnum
+ {
+ ///
+ /// Default value if a status has not yet been initialized.
+ ///
+ None,
+
+ ///
+ /// This is set when the SensorNetworkServer receives a request to send an initialization to the
+ /// Sensor Network.
+ ///
+ Initializing,
+
+ ///
+ /// This is set as soon as the SensorNetworkServer receives the first packet of sensor data from
+ /// the Sensor Network.
+ ///
+ ReceivingData,
+
+ ///
+ /// This is set if it takes too long to receive a data packet.
+ ///
+ TimedOutDataRetrieval,
+
+ ///
+ /// This is set if the Sensor Network takes too long to start sending data after the SensorNetworkClient
+ /// successfully sends the initialization.
+ ///
+ TimedOutInitialization,
+
+ ///
+ /// This is set if the SensorNetworkClient fails to send the initialization to the Sensor Network. This can
+ /// happen if the Sensor Network is not on, not plugged in (via Ethernet), or the user may have typed the
+ /// incorrect Client IP address/Port.
+ ///
+ InitializationSendingFailed,
+
+ ///
+ /// This is used if the SensorNetworkServer fails while running for any reason. Reasons could be that the IP address
+ /// is already taken, or the Ethernet cable was unplugged. The server doesn't depend on initially making a connection
+ /// (it waits until something connects to it), so as long as the IP address is valid and reachable at all times, this
+ /// error should not occur.
+ ///
+ ServerError,
+
+ ///
+ /// This status is set whenever a reboot is called. This will be overwritten very quickly by initialization as soon as the
+ /// sensor network starts back up.
+ ///
+ Rebooting,
+
+ ///
+ /// This means that the transit ID that was received and we are either not receiving complete packets, or the packets are
+ /// coming through broken.
+ ///
+ TransitIdError,
+
+ ///
+ /// This should never be reached, but if it is, then some troubleshooting needs to happen. The only way this can be set is
+ /// if the timer is elapsed and the status is not ReceivingData or Initializing.
+ ///
+ UnknownError
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Enumerations/TemperatureErrorCodes.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Enumerations/TemperatureErrorCodes.cs
new file mode 100644
index 00000000..fe4f1996
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Enumerations/TemperatureErrorCodes.cs
@@ -0,0 +1,29 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ControlRoomApplication.Controllers.SensorNetwork.Enumerations
+{
+ ///
+ /// Denotes what specific errors a temperature sensor may be having.
+ ///
+ public enum TemperatureErrorCodes
+ {
+ ///
+ /// The sensor is working properly.
+ ///
+ NoError,
+
+ ///
+ /// The sensor is not receiving data.
+ ///
+ NoData,
+
+ ///
+ /// The cyclic redundancy check for the sensor was invalid.
+ ///
+ CrcInvalid
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/PacketDecodingTools.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/PacketDecodingTools.cs
new file mode 100644
index 00000000..201b1e32
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/PacketDecodingTools.cs
@@ -0,0 +1,142 @@
+using ControlRoomApplication.Entities;
+using ControlRoomApplication.Entities.DiagnosticData;
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ControlRoomApplication.Controllers.SensorNetwork
+{
+ ///
+ /// Various functions that we will be using to decode the packets.
+ ///
+ public class PacketDecodingTools
+ {
+
+ ///
+ /// This is a helper function to get the acceleration array from the byte data.
+ ///
+ /// This is the current place we are in the byte array. We want to pass this by reference
+ /// so that future functions know where to begin.
+ /// This is the byte array that we are converting in to acceleration.
+ /// This is the size of the acceleration dumps that we expect to see in the byte array.
+ /// This is the sensor that the data is being created for.
+ /// This is an offset applied to the incoming sensor data timestamps to get more accurate readings.
+ ///
+ public static Acceleration[] GetAccelerationFromBytes(ref int currPointer, byte[] data, int size, SensorLocationEnum sensor, long timeOffset = 0)
+ {
+ // Default sampling frequency for accelerometers is 800 Hz
+ double samplingFrequency = 800;
+
+ // Determine which frequency to use in time calculations based on sensor location
+ switch (sensor)
+ {
+ case SensorLocationEnum.AZ_MOTOR:
+ samplingFrequency = SensorNetworkConstants.AzAccelSamplingFrequency;
+ break;
+ case SensorLocationEnum.EL_MOTOR:
+ samplingFrequency = SensorNetworkConstants.ElAccelSamplingFrequency;
+ break;
+ case SensorLocationEnum.COUNTERBALANCE:
+ samplingFrequency = SensorNetworkConstants.CbAccelSamplingFrequency;
+ break;
+ }
+
+ // Parse acceleration data from packet
+ List acceleration = new List();
+ for (int j = 0; j < size; j++)
+ {
+ // Parse out timestamp from first 8 bytes
+ long timeStamp = (data[currPointer++] << 56 | data[currPointer++] << 48 | data[currPointer++] << 40 | data[currPointer++] << 32
+ | data[currPointer++] << 24 | data[currPointer++] << 16 | data[currPointer++] << 8 | data[currPointer++]);
+
+ // Apply timestamp offset
+ timeStamp += timeOffset;
+
+ // Get the acceleration dump size from next 2 bytes
+ short dumpSize = (short)(data[currPointer++] << 8 | data[currPointer++]);
+
+ // Parse acceleration samples
+ for (int k = 0; k < dumpSize; k++)
+ {
+ acceleration.Add(Acceleration.Generate(
+ // Timestamp is for the last acceleration value taken, so compute the difference for each acceleration value up to the timestamp
+ timeStamp - (long)((dumpSize - (k + 1)) / samplingFrequency * 1000),
+ (short)(data[currPointer++] << 8 | data[currPointer++]),
+ (short)(data[currPointer++] << 8 | data[currPointer++]),
+ (short)(data[currPointer++] << 8 | data[currPointer++]),
+ sensor
+ ));
+ }
+ }
+
+ return acceleration.ToArray();
+ }
+
+ ///
+ /// This is a helper function to get the temperature data from the byte array we receive from the Sensor Network.
+ ///
+ /// This is the current place we are in the byte array. We want to pass this by reference
+ /// so that future functions know where to begin.
+ /// This is the byte array that we are converting in to acceleration.
+ /// This is the size of the acceleration data that we expect to see in the byte array.
+ /// This is the sensor that the data is being created for.
+ ///
+ public static Temperature[] GetTemperatureFromBytes(ref int currPointer, byte[] data, int size, SensorLocationEnum sensor)
+ {
+
+ Temperature[] temperature = new Temperature[size];
+ for (int j = 0; j < size; j++)
+ {
+ temperature[j] = Temperature.Generate(
+ DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
+ (double)((short)((data[currPointer++] << 8 | data[currPointer++]))) / 16, // Converting to Celsius by default because we receive raw data
+ sensor
+ );
+ }
+
+ return temperature;
+ }
+
+ ///
+ /// Converts two bytes to the azimuth position, then adds an offset and normalizes the orientation.
+ ///
+ /// Current index in the byte array.
+ /// Data we are converting to a double.
+ /// The offset to apply after double conversion.
+ /// The current position in case the one we get in is invalid.
+ /// Current azimuth position.
+ public static double GetAzimuthAxisPositionFromBytes(ref int currPointer, byte[] data, double offset, double currPos)
+ {
+ double azPos = 360 / SensorNetworkConstants.AzimuthEncoderScaling * (short)(data[currPointer++] << 8 | data[currPointer++]);
+
+ if (Math.Abs(azPos) > 360) return currPos;
+
+ double azPosOffs = (azPos + offset) * -1;
+
+ // Because the offset could cause the axis position to be negative, we want to normalize that to a positive value.
+ while (azPosOffs < 0) azPosOffs += 360;
+
+ return azPosOffs;
+ }
+
+ ///
+ /// Converts two bytes to the elevation position, then adds an offset to the position.
+ ///
+ /// Current index in the byte array.
+ /// Data we are converting to a double.
+ /// The offset to apply after double conversion.
+ /// The current position in case the one we get in is invalid.
+ /// Current elevation position.
+ public static double GetElevationAxisPositionFromBytes(ref int currPointer, byte[] data, double offset, double currPos)
+ {
+ double elPos = -0.25 * (short)(data[currPointer++] << 8 | data[currPointer++]) + 104.375;
+
+ double elPosOffs = (elPos - offset);
+
+ return elPosOffs;
+ }
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/SensorNetworkClient.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/SensorNetworkClient.cs
new file mode 100644
index 00000000..0b64e9ac
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/SensorNetworkClient.cs
@@ -0,0 +1,89 @@
+using ControlRoomApplication.Database;
+using ControlRoomApplication.Entities;
+using ControlRoomApplication.Util;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.Sockets;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ControlRoomApplication.Controllers.SensorNetwork
+{
+ ///
+ /// This is the class used to send sensor initialization information to the Sensor Network.
+ ///
+ public class SensorNetworkClient
+ {
+ private static readonly log4net.ILog logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
+
+ ///
+ /// Constructor used to initialize a SensorNetworkClient, which will allow the SensorNetworkServer
+ /// to use this to send data to the Sensor Network.
+ ///
+ /// IP address that the client will connect to.
+ /// Port that the client will connect to.
+ /// The ID of the Radio Telescope so we know what config to grab.
+ public SensorNetworkClient(string clientIPAddress, int clientPort, int telescopeId)
+ {
+ IPAddress = clientIPAddress;
+ Port = clientPort;
+ SensorNetworkConfig = DatabaseOperations.RetrieveSensorNetworkConfigByTelescopeId(telescopeId);
+
+ // if the config doesn't exist, create a new one
+ if(SensorNetworkConfig == null)
+ {
+ SensorNetworkConfig = new SensorNetworkConfig(telescopeId);
+ DatabaseOperations.AddSensorNetworkConfig(SensorNetworkConfig);
+ }
+ }
+
+ private TcpClient InitializationClient;
+ private readonly string IPAddress;
+ private readonly int Port;
+
+ ///
+ /// This is the configuration we are using to store any initialization data to send, as well
+ /// as timeout information.
+ ///
+ public SensorNetworkConfig SensorNetworkConfig;
+
+ ///
+ /// Converts the initialization from the config file to bytes and then sends it to the Sensor Network.
+ ///
+ public bool SendSensorInitialization()
+ {
+ bool success = false;
+ var init = SensorNetworkConfig.GetSensorInitAsBytes();
+
+ try
+ {
+ // Set up TCP client
+ InitializationClient = new TcpClient(IPAddress, Port);
+ NetworkStream stream = InitializationClient.GetStream();
+
+ // Send initialization
+ stream.Write(init, 0, init.Length);
+
+ stream.Flush();
+ stream.Close();
+ stream.Dispose();
+ InitializationClient.Close();
+ InitializationClient.Dispose();
+
+ success = true; // Successfully sent the message without any errors
+ }
+
+ // Reaching this exception will set the SensorNetworkServer's status to InitializationSendingFailed
+ catch (SocketException)
+ {
+ logger.Info(Utilities.GetTimeStamp() + $": There was an error sending data to the Sensor Network at {IPAddress}:{Port}; " +
+ $"the address:port may be busy or no server was found. Please verify the address:port is available and restart the " +
+ $"Control Room software.");
+ }
+
+ return success;
+ }
+
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/SensorNetworkConstants.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/SensorNetworkConstants.cs
new file mode 100644
index 00000000..66a4a1af
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/SensorNetworkConstants.cs
@@ -0,0 +1,109 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ControlRoomApplication.Controllers.SensorNetwork
+{
+ ///
+ /// This will contain all of the various constants that the SensorNetwork components need
+ /// to use. These values may contain data conversions, simulation intervals, and so on.
+ ///
+ public sealed class SensorNetworkConstants
+ {
+
+ ///
+ /// This is a constant needed for converting the raw azimuth data received from the
+ /// absolute azimuth encoder to degrees, which the user will see.
+ /// This is based on the resolution of the digital data that the encoder gives.
+ /// The angle is related from 0-360 in digital counts from 0-2047.
+ ///
+ public const double AzimuthEncoderScaling = 2047;
+
+ ///
+ /// This is the approximate interval at which the SensorNetworkServer expects to receive
+ /// data from the Sensor Network. Because the transfer isn't perfect, there will be an additional
+ /// ~50ms delay. For example, a 250ms interval will yield about a 300ms receive interval.
+ /// This is also used in the SensorNetworkSimulation.
+ ///
+ public const int DataSendingInterval = 250; // in milliseconds
+
+ ///
+ /// This is the default data retrieval timeout when the user has run the telescope for the first time,
+ /// and a new SensorNetworkConfig is created.
+ ///
+ public const int DefaultDataRetrievalTimeout = 1000; // in milliseconds
+
+ ///
+ /// This is the default initialization timeout when the user has run the telescope for the first time,
+ /// and a new SensorNetworkConfig is created.
+ ///
+ public const int DefaultInitializationTimeout = 10000; // in milliseconds
+
+ ///
+ /// This is the total number of Sensor Network sensors that can be receiving data at a given time.
+ /// This is used to determine the byte size of the initialization.
+ ///
+ public const int SensorNetworkSensorCount = 7;
+
+ ///
+ /// If we receive this ID from the sensor network, it means that everything is going well, and we are about
+ /// to get a nice load of sensor data. The number doesn't come from anything, it's just the number we chose.
+ ///
+ public const int TransitIdSuccess = 129;
+
+ ///
+ /// This is the max packet size the Sensor Network is able to send. We aren't really sure why it cuts off
+ /// at 2048, but for this reason, this is the size that we will create our main "monitor" byte array.
+ ///
+ public const int MaxPacketSize = 2048; // in bytes
+
+ ///
+ /// This is how long it takes for the sensor network to time out and reboot. Basically, if it loses connection
+ /// to the SensorNetworkServer for that amount of ms, it will trigger a reboot. This is useful to us for when we
+ /// want to tell it to restart.
+ ///
+ public const int WatchDogTimeout = 1500; // in milliseconds
+
+ ///
+ /// This is where our simulation CSV files are located. These files can be swapped out with each other.
+ ///
+ public const string SimCSVDirectory = "../../Controllers/SensorNetwork/Simulation/SimulationCSVData/";
+
+ ///
+ /// This is the FIFO size used by the azimuth motor accelerometer
+ ///
+ public const int AzAccelFIFOSize = 32;
+
+ ///
+ /// This is the FIFO size used by the elevation motor accelerometer
+ ///
+ public const int ElAccelFIFOSize = 32;
+
+ ///
+ /// This is the FIFO size used by the counterbalance accelerometer
+ ///
+ public const int CbAccelFIFOSize = 32;
+
+ ///
+ /// This is the sampling frequency used by the azimuth motor accelerometer
+ ///
+ public const double AzAccelSamplingFrequency = 800;
+
+ ///
+ /// This is the sampling frequency used by the elevation motor accelerometer
+ ///
+ public const double ElAccelSamplingFrequency = 800;
+
+ ///
+ /// This is the sampling frequency used by the counterbalance accelerometer
+ ///
+ public const double CbAccelSamplingFrequency = 800;
+
+ ///
+ /// This is the degrees offset manually applied to the counterbalance accelerometer position used for greater precision.
+ ///
+ public const double CBAccelPositionOffset = 2;
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/SensorNetworkServer.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/SensorNetworkServer.cs
new file mode 100644
index 00000000..be0d632f
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/SensorNetworkServer.cs
@@ -0,0 +1,582 @@
+using ControlRoomApplication.Entities;
+using ControlRoomApplication.Util;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Net.Sockets;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Timers;
+using ControlRoomApplication.Controllers.SensorNetwork.Simulation;
+using ControlRoomApplication.Controllers.Communications;
+using System.Collections;
+using ControlRoomApplication.Entities.DiagnosticData;
+
+namespace ControlRoomApplication.Controllers.SensorNetwork
+{
+
+ ///
+ /// This is the central component of the Sensor Network on the Control Room end. This handles all the main communications
+ /// with the main Sensor Network system, such as receiving data, setting statuses based on data it receives, and tells the
+ /// client when to send initialization data.
+ ///
+ public class SensorNetworkServer : PacketDecodingTools
+ {
+ private static readonly log4net.ILog logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
+
+ ///
+ /// Constructor used to set the values needed to initialize the components of the class. It will not start waiting for data until
+ /// StartSensorMonitoringRoutine() is called.
+ ///
+ /// The reason the client IP address is a string and not an IPAddress is because none of the TCPClient class's
+ /// constructors take an IPAddress. :(
+ ///
+ /// This is the IP address the SensorNetworkServer is "listening" to.
+ /// This is the port the SensorNetworkServer is "listening" to.
+ /// This is the IP address of the SensorNetwork that we will be sending the sensor initialization to.
+ /// This is the port of the SensorNetwork that we will be sending the sensor initialization to.
+ /// The Radio Telescope that the SensorNetworkConfig will apply to.
+ /// Tells the SensorNetworkServer if it should initialize the SimulationSensorNetwork,
+ /// or if it is connecting to the production hardware (or maybe an outside simulation).
+ public SensorNetworkServer(IPAddress serverIPAddress, int serverPort, string clientIPAddress, int clientPort, int telescopeId, bool isSimulation)
+ {
+ // Initialize main parts of the Sensor Network
+ Server = new TcpListener(serverIPAddress, serverPort);
+ InitializationClient = new SensorNetworkClient(clientIPAddress, clientPort, telescopeId);
+
+ // Sensor data initialization
+ CurrentElevationMotorTemp = new Temperature[1];
+ CurrentElevationMotorTemp[0] = new Temperature();
+
+ CurrentAzimuthMotorTemp = new Temperature[1];
+ CurrentAzimuthMotorTemp[0] = new Temperature();
+
+ CurrentAbsoluteOrientation = new Orientation();
+
+ CurrentElevationMotorAccl = new Acceleration[1];
+ CurrentElevationMotorAccl[0] = new Acceleration();
+
+ CurrentAzimuthMotorAccl = new Acceleration[1];
+ CurrentAzimuthMotorAccl[0] = new Acceleration();
+
+ CurrentCounterbalanceAccl = new Acceleration[1];
+ CurrentCounterbalanceAccl[0] = new Acceleration();
+
+ AbsoluteOrientationOffset = new Orientation();
+
+ // Sensor error initialization
+ SensorStatuses = new SensorStatuses();
+ SensorStatuses.AzimuthAbsoluteEncoderStatus = SensorNetworkSensorStatus.Okay;
+ SensorStatuses.ElevationAbsoluteEncoderStatus = SensorNetworkSensorStatus.Okay;
+ SensorStatuses.AzimuthTemperature1Status = SensorNetworkSensorStatus.Okay;
+ SensorStatuses.AzimuthTemperature2Status = SensorNetworkSensorStatus.Okay;
+ SensorStatuses.ElevationTemperature1Status = SensorNetworkSensorStatus.Okay;
+ SensorStatuses.ElevationTemperature2Status = SensorNetworkSensorStatus.Okay;
+ SensorStatuses.AzimuthAccelerometerStatus = SensorNetworkSensorStatus.Okay;
+ SensorStatuses.ElevationAccelerometerStatus = SensorNetworkSensorStatus.Okay;
+ SensorStatuses.CounterbalanceAccelerometerStatus = SensorNetworkSensorStatus.Okay;
+
+ // Initialize threads and additional processes, if applicable
+ SensorMonitoringThread = new Thread(() => { SensorMonitoringRoutine(); });
+ SensorMonitoringThread.Name = "SensorMonitorThread";
+
+ // We only want to run the internal simulation if the user selected to run the Simulated Sensor Network
+ if (isSimulation)
+ {
+ SimulationSensorNetwork = new SimulationSensorNetwork(serverIPAddress.ToString(), serverPort, IPAddress.Parse(clientIPAddress), clientPort);
+ }
+ else
+ {
+ SimulationSensorNetwork = null;
+ }
+
+ // Initialize the timeout timer but don't start it yet
+ Timeout = new System.Timers.Timer();
+ Timeout.Elapsed += TimedOut; // TimedOut is the function at the bottom that executes when this elapses
+ Timeout.AutoReset = false;
+
+ AzimuthAccBlob = new AzimuthAccelerationBlob();
+ ElevationAccBlob = new ElevationAccelerationBlob();
+ CounterbalanceAccBlob = new CounterbalanceAccelerationBlob();
+
+ }
+
+ ///
+ /// The current elevation motor temperature received from the sensor network.
+ ///
+ public Temperature[] CurrentElevationMotorTemp { get; set; }
+
+ ///
+ /// The current azimuth motor temperature received from the sensor network.
+ ///
+ public Temperature[] CurrentAzimuthMotorTemp { get; set; }
+
+ ///
+ /// The current orientation of the telescope based off of the absolute encoders. These
+ /// are totally separate from the motor encoders' data that we get from the GetMotorEncoderPosition
+ /// function in the PLC and MCU, and will provide more accurate data regarding the telescope's
+ /// position.
+ ///
+ public Orientation CurrentAbsoluteOrientation { get; set; }
+
+ ///
+ /// The absolute encoders will be different from the motor encoders by default, so when we home the telescope,
+ /// the offset will be calculated and stored in here. This should work no matter where the homing sensor
+ /// is placed.
+ ///
+ public Orientation AbsoluteOrientationOffset { get; set; }
+
+ ///
+ /// This tells us the current vibration coming from the azimuth motor. It is always received as
+ /// an array to give us higher data accuracy.
+ ///
+ public Acceleration[] CurrentElevationMotorAccl { get; set; }
+
+ ///
+ /// This tells us the current vibration coming from the azimuth motor. It is always received as
+ /// an array to give us higher data accuracy.
+ ///
+ public Acceleration[] CurrentAzimuthMotorAccl { get; set; }
+
+ ///
+ /// This tells us the current vibration coming from the counterbalance. It is always received as
+ /// an array to give us higher data accuracy. This can also technically be used to calculate the
+ /// telescope's elevation position.
+ ///
+ public Acceleration[] CurrentCounterbalanceAccl { get; set; }
+
+ ///
+ /// This is the current orientation calculated from the counterbalance. It is updated with every
+ /// packet recieved from the sensor network.
+ ///
+ public double CurrentCBAccelElevationPosition { get; set; }
+
+ ///
+ /// This is used for sending initialization data to the Sensor Network, and is also used to
+ /// access the configuration.
+ ///
+ public SensorNetworkClient InitializationClient { get; }
+
+ ///
+ /// This is the simulation sensor network, which will run whenever we are not using the hardware.
+ ///
+ public SimulationSensorNetwork SimulationSensorNetwork { get; }
+
+ ///
+ /// This will be used to tell us what the SensorNetwork status using .
+ ///
+ public SensorNetworkStatusEnum Status { get; set; }
+
+ ///
+ /// This contains data for the individual sensors' statuses.
+ ///
+ public SensorStatuses SensorStatuses { get; set; }
+
+ ///
+ /// These two objects are used together to receive data, and should be destroyed together as well.
+ ///
+ private TcpListener Server;
+ private NetworkStream Stream;
+
+ ///
+ /// This should be true as long as the SensorMonitoringThread is running, and set to false if that thread
+ /// is to be terminated.
+ ///
+ private bool CurrentlyRunning { get; set; }
+
+ ///
+ /// This thread should always be running and waiting or collecting some kind of data from the Sensor Network unless
+ /// the CurrentlyRunning value (above) is set to false.
+ ///
+ private Thread SensorMonitoringThread { get; set; }
+
+ ///
+ /// This will help us detect if the SensorNetworkServer has stopped receiving data.
+ ///
+ private System.Timers.Timer Timeout { get; }
+
+ ///
+ /// This will be used to help send acceleration data to the database
+ ///
+ private AzimuthAccelerationBlob AzimuthAccBlob { get; set; }
+
+ ///
+ /// This will be used to help send acceleration data to the database
+ ///
+ private ElevationAccelerationBlob ElevationAccBlob { get; set; }
+
+ ///
+ /// This will be used to help send acceleration data to the database
+ ///
+ private CounterbalanceAccelerationBlob CounterbalanceAccBlob { get; set; }
+
+ ///
+ /// This stores the timestamp that the sensor network server got connected with a client
+ ///
+ private long ConnectionTimestamp { get; set; }
+
+ ///
+ /// This starts the SensorMonitoringRoutine. Calling this will immediately begin initialization.
+ ///
+ /// If started successfully, return true. Else, return false.
+ public void StartSensorMonitoringRoutine(bool rebooting = false)
+ {
+ Server.Start();
+ CurrentlyRunning = true;
+ Status = SensorNetworkStatusEnum.Initializing;
+ Timeout.Interval = InitializationClient.SensorNetworkConfig.TimeoutInitialization;
+ Timeout.Start();
+ SensorMonitoringThread.Start();
+
+ if (SimulationSensorNetwork != null && !rebooting)
+ {
+ SimulationSensorNetwork.StartSimulationSensorNetwork();
+ }
+ }
+
+ ///
+ /// This ends the SensorMonitoringRoutine. This should only be executed when "Shutdown RT" is clicked.
+ ///
+ /// This will tell the function if we are rebooting, or shutting down indefinitely.
+ /// If ended successfully, return true. Else, return false.
+ public void EndSensorMonitoringRoutine(bool rebooting = false)
+ {
+ CurrentlyRunning = false;
+ // The stream will only be null if the sensor monitoring thread has not been called
+ if (Stream != null)
+ {
+ Stream.Close();
+ Stream.Dispose();
+ }
+
+ Server.Stop();
+
+ if (Timeout.Enabled) Timeout.Stop();
+
+ SensorMonitoringThread.Join();
+
+ if (!rebooting)
+ { // We want to keep using the timer if we are rebooting, not destroy it.
+ Status = SensorNetworkStatusEnum.None;
+ Timeout.Dispose();
+
+ if (SimulationSensorNetwork != null)
+ {
+ SimulationSensorNetwork.EndSimulationSensorNetwork();
+ }
+ }
+ else
+ {
+ Status = SensorNetworkStatusEnum.Rebooting;
+ SensorMonitoringThread = new Thread(() => { SensorMonitoringRoutine(); });
+ }
+ }
+
+ ///
+ /// This will reboot the Sensor Network, which will update its sensor initialization with what the
+ /// user has selected on the GUI.
+ ///
+ ///
+ public void RebootSensorNetwork()
+ {
+ logger.Info($"{Utilities.GetTimeStamp()}: Rebooting Sensor Network. This may take a few seconds...");
+
+ EndSensorMonitoringRoutine(true); // Must pass through true because we are rebooting
+
+ // This is to let the Sensor Network time out, triggering a reboot. We're adding 50ms on to this to make
+ // sure it REALLY times out.
+ Thread.Sleep(SensorNetworkConstants.WatchDogTimeout + 50);
+
+ StartSensorMonitoringRoutine(true);
+ }
+
+ ///
+ /// This is used internally by the SensorNetworkServer to tell what kind of data the Sensor Network
+ /// is sending. It may send data, in which case a transit ID will be present, or it may ask for
+ /// an initialization.
+ ///
+ /// The data we are interpreting.
+ /// This will be used to tell if our data is complete.
+ private bool InterpretData(byte[] data, int receivedDataSize)
+ {
+ bool success = false;
+
+ if(Encoding.ASCII.GetString(data, 0, receivedDataSize).Equals("Send Sensor Configuration"))
+ { // Reaching here means that we've received a request for sensor initialization
+ Status = SensorNetworkStatusEnum.Initializing;
+
+ // If the init sending fails, set status to reflect that
+ if (!InitializationClient.SendSensorInitialization())
+ {
+ Status = SensorNetworkStatusEnum.InitializationSendingFailed;
+ if(Timeout.Enabled) Timeout.Stop();
+
+ pushNotification.sendToAllAdmins("Sensor Network Error", $"Status: {Status}");
+ }
+ else
+ {
+ ConnectionTimestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
+ logger.Info($"{Utilities.GetTimeStamp()}: Successfully sent sensor initialization to the Sensor Network.");
+ success = true;
+ }
+ }
+ else
+ {
+ Status = SensorNetworkStatusEnum.ReceivingData;
+
+ // Bytes 1-3 of the data contain the overall size of the packet
+ UInt32 expectedDataSize = (UInt32)(data[1] << 24 | data[2] << 16 | data[3] << 8 | data[4]);
+
+ // Check that the data we received is the same size as what we expect
+ if (expectedDataSize == receivedDataSize)
+ {
+ // Byte 0 contains the transmit ID
+ int receivedTransitId = data[0];
+
+ // Verify that the first byte contains the "success" code (transit ID)
+ if(receivedTransitId == SensorNetworkConstants.TransitIdSuccess)
+ {
+ // At this point, we may begin parsing the data
+
+ // Sensor statuses and error codes
+ BitArray sensorStatus = new BitArray(new byte[] { data[5] }); // sensor statuses
+ UInt32 sensorErrors = (UInt32)(data[6] << 16 | data[7] << 8 | data[8]); // sensor self-tests | adxl error codes and azimuth encoder error code | temp sensor error codes
+
+ // Acquire the sample sizes for each sensor
+ UInt16 elAcclSize = (UInt16)(data[9] << 8 | data[10]);
+ UInt16 azAcclSize = (UInt16)(data[11] << 8 | data[12]);
+ UInt16 cbAcclSize = (UInt16)(data[13] << 8 | data[14]);
+ UInt16 elTempSensorSize = (UInt16)(data[15] << 8 | data[16]);
+ UInt16 azTempSensorSize = (UInt16)(data[17] << 8 | data[18]);
+ UInt16 elEncoderSize = (UInt16)(data[19] << 8 | data[20]);
+ UInt16 azEncoderSize = (UInt16)(data[21] << 8 | data[22]);
+
+ // TODO: Outside of right here, we aren't doing anything with the sensor statuses. These should
+ // be updated along with the sensor data on the diagnostics form. How this looks is up to you. (issue #353)
+ SensorStatuses = ParseSensorStatuses(sensorStatus, sensorErrors);
+
+ // This is the index we start reading sensor data
+ int k = 23;
+
+ // If no data comes through for a sensor (i.e. the size is 0), then it will not be updated,
+ // otherwise the UI value would temporarily be set to 0, which would be inaccurate
+
+ // Accelerometer 1 (elevation)
+ if (elAcclSize > 0)
+ {
+ //Create array of acceleration objects
+ CurrentElevationMotorAccl = GetAccelerationFromBytes(ref k, data, elAcclSize, SensorLocationEnum.EL_MOTOR, ConnectionTimestamp);
+ ElevationAccBlob.BuildAccelerationBlob(CurrentElevationMotorAccl);
+ }
+
+ // Accelerometer 2 (azimuth)
+ if (azAcclSize > 0)
+ {
+ CurrentAzimuthMotorAccl = GetAccelerationFromBytes(ref k, data, azAcclSize, SensorLocationEnum.AZ_MOTOR, ConnectionTimestamp);
+ AzimuthAccBlob.BuildAccelerationBlob(CurrentAzimuthMotorAccl);
+ }
+
+ // Accelerometer 3 (counterbalance)
+ if (cbAcclSize > 0)
+ {
+ CurrentCounterbalanceAccl = GetAccelerationFromBytes(ref k, data, cbAcclSize, SensorLocationEnum.COUNTERBALANCE, ConnectionTimestamp);
+ CounterbalanceAccBlob.BuildAccelerationBlob(CurrentCounterbalanceAccl);
+
+ // If there is new counterbalance accelerometer data, update the elevation position
+ UpdateCBAccelElevationPosition();
+ }
+
+ // Elevation temperature
+ if (elTempSensorSize > 0)
+ {
+ CurrentElevationMotorTemp = GetTemperatureFromBytes(ref k, data, elTempSensorSize, SensorLocationEnum.EL_MOTOR);
+ Database.DatabaseOperations.AddSensorData(CurrentElevationMotorTemp);
+ }
+
+ // Azimuth temperature
+ if (azTempSensorSize > 0)
+ {
+ CurrentAzimuthMotorTemp = GetTemperatureFromBytes(ref k, data, azTempSensorSize, SensorLocationEnum.AZ_MOTOR);
+ Database.DatabaseOperations.AddSensorData(CurrentAzimuthMotorTemp);
+ }
+
+ // Elevation absolute encoder
+ if (elEncoderSize > 0)
+ {
+ CurrentAbsoluteOrientation.Elevation = GetElevationAxisPositionFromBytes(ref k, data, AbsoluteOrientationOffset.Elevation, CurrentAbsoluteOrientation.Elevation);
+ }
+
+ // Azimuth absolute encoder
+ if (azEncoderSize > 0)
+ {
+ CurrentAbsoluteOrientation.Azimuth = GetAzimuthAxisPositionFromBytes(ref k, data, AbsoluteOrientationOffset.Azimuth, CurrentAbsoluteOrientation.Azimuth);
+ }
+
+ success = true;
+ }
+
+ // This may be replaced with different errors at some point (that have different transit IDs),
+ // though there are currently no plans for this. Right now, it is treated as an error overall:
+ // We should NOT be receiving anything other than TransitIdSuccess.
+ else
+ {
+ if (Status != SensorNetworkStatusEnum.TransitIdError)
+ {
+ logger.Error($"{Utilities.GetTimeStamp()}: Transit ID error: Expected " +
+ $"ID {SensorNetworkConstants.TransitIdSuccess}, received ID {receivedTransitId})");
+
+ Status = SensorNetworkStatusEnum.TransitIdError;
+ }
+ }
+ }
+ }
+
+ return success;
+ }
+
+ ///
+ /// This is the main routine that will constantly be expecting data from the Sensor Network. This will
+ /// continuously run in a loop until EndSensorMonitoringRoutine() is called.
+ ///
+ private void SensorMonitoringRoutine()
+ {
+ TcpClient localClient;
+
+ byte[] receivedData = new byte[SensorNetworkConstants.MaxPacketSize];
+
+ while(CurrentlyRunning)
+ {
+ try
+ {
+ localClient = Server.AcceptTcpClient();
+ Stream = localClient.GetStream();
+
+ logger.Info($"{Utilities.GetTimeStamp()}: Successfully connected to the Sensor Network!");
+
+ int receivedDataSize;
+
+ while ((receivedDataSize = Stream.Read(receivedData, 0, receivedData.Length)) != 0 && CurrentlyRunning)
+ {
+ // If the status is initializing, we want the timer to keep going. Else, we are currently receiving data, and
+ // want to stop the timer as soon as we get something.
+ if (Timeout.Enabled && Status == SensorNetworkStatusEnum.ReceivingData)
+ {
+ Timeout.Stop();
+ }
+
+ InterpretData(receivedData, receivedDataSize);
+
+ // We only want to start the timeout if we are currently receiving data. The reason is because, the timeout
+ // status will overwrite any preexisting status errors.
+ if (Status == SensorNetworkStatusEnum.ReceivingData)
+ {
+ Timeout.Interval = InitializationClient.SensorNetworkConfig.TimeoutDataRetrieval;
+ Timeout.Start();
+ }
+ }
+
+ localClient.Close();
+ localClient.Dispose();
+ }
+ catch (Exception e)
+ {
+ if (CurrentlyRunning) // If we're not currently running, then it means we voluntarily shut down the server
+ {
+ Timeout.Stop();
+ Status = SensorNetworkStatusEnum.ServerError;
+ logger.Error($"{Utilities.GetTimeStamp()}: An error occurred while running the server; please check that the connection is available.");
+ logger.Info($"{Utilities.GetTimeStamp()}: Trying to reconnect to the Sensor Network...");
+
+ pushNotification.sendToAllAdmins("Sensor Network Error", $"Status: {Status}");
+ }
+ }
+ }
+ }
+
+ ///
+ /// This is used to parse the sensor statuses into the SensorStatuses object.
+ ///
+ /// Regular statuses.
+ /// Various error codes if there are errors.
+ ///
+ private SensorStatuses ParseSensorStatuses(BitArray statuses, UInt32 errors)
+ {
+ SensorStatuses s = new SensorStatuses
+ {
+ // Regular statuses
+ AzimuthAbsoluteEncoderStatus = statuses[0] ? SensorNetworkSensorStatus.Okay : SensorNetworkSensorStatus.Error,
+ AzimuthTemperature1Status = statuses[2] ? SensorNetworkSensorStatus.Okay : SensorNetworkSensorStatus.Error,
+ AzimuthTemperature2Status = statuses[1] ? SensorNetworkSensorStatus.Okay : SensorNetworkSensorStatus.Error,
+ ElevationTemperature1Status = statuses[4] ? SensorNetworkSensorStatus.Okay : SensorNetworkSensorStatus.Error,
+ ElevationTemperature2Status = statuses[3] ? SensorNetworkSensorStatus.Okay : SensorNetworkSensorStatus.Error,
+ AzimuthAccelerometerStatus = statuses[6] ? SensorNetworkSensorStatus.Okay : SensorNetworkSensorStatus.Error,
+ ElevationAccelerometerStatus = statuses[7] ? SensorNetworkSensorStatus.Okay : SensorNetworkSensorStatus.Error,
+ CounterbalanceAccelerometerStatus = statuses[5] ? SensorNetworkSensorStatus.Okay : SensorNetworkSensorStatus.Error,
+
+ // TODO: Parse errors here. You will need to add the errors to the SensorStatuses object (issue #353)
+ };
+
+ return s;
+ }
+
+ ///
+ /// This is only reached when a timeout occurs from the Timer. One of the two TimedOut statuses will
+ /// be set as a result of this call.
+ ///
+ /// unused
+ /// unused
+ private void TimedOut(Object source, ElapsedEventArgs e)
+ {
+ if(Status == SensorNetworkStatusEnum.ReceivingData)
+ {
+ Status = SensorNetworkStatusEnum.TimedOutDataRetrieval;
+ }
+ else if(Status == SensorNetworkStatusEnum.Initializing)
+ {
+ Status = SensorNetworkStatusEnum.TimedOutInitialization;
+ }
+ else
+ {
+ Status = SensorNetworkStatusEnum.UnknownError;
+ }
+
+ logger.Error($"{Utilities.GetTimeStamp()}: Connection to the Sensor Network timed out! Status: {Status}");
+
+ pushNotification.sendToAllAdmins("Sensor Network Timeout", $"Status: {Status}");
+ }
+
+ ///
+ /// Update the counterbalance accelerometer position with the data currently in CurrentCounterBalanceAccl
+ ///
+ private void UpdateCBAccelElevationPosition()
+ {
+ double y_sum = 0, z_sum = 0, x_sum = 0;
+
+ for (int i = 0; i < CurrentCounterbalanceAccl.Length; i++)
+ {
+ // Gather a sum of all the accerlometer data
+ y_sum += CurrentCounterbalanceAccl[i].y;
+ z_sum += CurrentCounterbalanceAccl[i].z;
+ x_sum += CurrentCounterbalanceAccl[i].x;
+ }
+
+ // Get an average of all accelerometer data for a more precise reading
+ double y_avg = y_sum / CurrentCounterbalanceAccl.Length;
+ double x_avg = x_sum / CurrentCounterbalanceAccl.Length;
+ double z_avg = z_sum / CurrentCounterbalanceAccl.Length;
+ //Console.WriteLine("X: " + x_avg + " Y: " + y_avg + " Z: " + z_avg);
+
+ // Map the accerlerometer output values to their proper G-force range
+ double X_out = x_avg / 256.0;
+ double Y_out = y_avg / 256.0;
+ double Z_out = z_avg / 256.0;
+ //Console.WriteLine("X: " + X_out + " Y: " + Y_out + " Z: " + Z_out);
+
+ //Console.WriteLine(Math.Atan2(Y_out, -Z_out) * 180.0 / Math.PI + SensorNetworkConstants.CBAccelPositionOffset);
+ // Calculate roll orientation
+ CurrentCBAccelElevationPosition = Math.Atan2(Y_out, -Z_out) * 180.0 / Math.PI + SensorNetworkConstants.CBAccelPositionOffset;
+ }
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Simulation/PacketEncodingTools.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Simulation/PacketEncodingTools.cs
new file mode 100644
index 00000000..87712ea0
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Simulation/PacketEncodingTools.cs
@@ -0,0 +1,364 @@
+using ControlRoomApplication.Controllers.SensorNetwork;
+using ControlRoomApplication.Controllers.SensorNetwork.Simulation;
+using ControlRoomApplication.Entities.DiagnosticData;
+using System;
+
+namespace EmbeddedSystemsTest.SensorNetworkSimulation
+{
+ ///
+ /// This contains helper functions to allow us to encode data in the same way the Sensor Network would before sending it to us.
+ /// The data it encodes will be data from CSVs, but it will "send" raw data to the SensorNetworkServer.
+ ///
+ public class PacketEncodingTools
+ {
+ ///
+ /// This is important for the simulation. This will convert the data arrays we get from CSV files
+ /// to bytes that we can send to the SensorNetworkServer.
+ ///
+ /// Array of RAW elevation accelerometer samples.
+ /// Array of RAW azimuth accelerometer samples.
+ /// Array of RAW counterbalance accelerometer samples.
+ /// Array of elevation temperature samples.
+ /// Array of azimuth temperature samples.
+ /// Array of elevation encoder samples.
+ /// Array of azimuth encoder samples.
+ /// All the sensor statuses and errors that come from the sensor network.
+ /// The time the sensor network connected to the control room. Used to generate simulated acceleration time captures
+ ///
+ public static byte[] ConvertDataArraysToBytes(RawAccelerometerData[] elAccl, RawAccelerometerData[] azAccl, RawAccelerometerData[] cbAccl, double[] elTemps, double[] azTemps, double[] elEnc, double[] azEnc, SensorStatuses statuses, long connectionTimeStamp)
+ {
+ uint dataSize = CalcDataSize(elAccl.Length, azAccl.Length, cbAccl.Length, elTemps.Length, azTemps.Length, elEnc.Length, azEnc.Length);
+
+ // If you want to input raw data instead, just comment out the next few loops.
+ // They exist so that we can input data into our CSV files that make sense to us, since
+ // raw data values are not very readable
+
+ // Convert elevation temperature to raw data
+ short[] rawElTemps = new short[elTemps.Length];
+ for (int i = 0; i < elTemps.Length; i++)
+ {
+ rawElTemps[i] = ConvertTempCToRawData(elTemps[i]);
+ }
+
+ // Convert azimuth temperature to raw data
+ short[] rawAzTemps = new short[azTemps.Length];
+ for (int i = 0; i < azTemps.Length; i++)
+ {
+ rawAzTemps[i] = ConvertTempCToRawData(azTemps[i]);
+ }
+
+ // Convert elevation position to raw data
+ short[] rawElEnc = new short[elEnc.Length];
+ for(int i = 0; i < elEnc.Length; i++)
+ {
+ rawElEnc[i] = ConvertDegreesToRawElData(elEnc[i]);
+ }
+
+ // Convert azimuth position to raw data
+ short[] rawAzEnc = new short[azEnc.Length];
+ for (int i = 0; i < azEnc.Length; i++)
+ {
+ rawAzEnc[i] = ConvertDegreesToRawAzData(azEnc[i]);
+ }
+
+ bool[] sensorStatusBoolArray = new bool[] {
+ statuses.ElevationAccelerometerStatus == SensorNetworkSensorStatus.Okay,
+ statuses.AzimuthAccelerometerStatus == SensorNetworkSensorStatus.Okay,
+ statuses.CounterbalanceAccelerometerStatus == SensorNetworkSensorStatus.Okay,
+ statuses.ElevationTemperature1Status == SensorNetworkSensorStatus.Okay,
+ statuses.ElevationTemperature2Status == SensorNetworkSensorStatus.Okay,
+ statuses.AzimuthTemperature1Status == SensorNetworkSensorStatus.Okay,
+ statuses.AzimuthTemperature2Status == SensorNetworkSensorStatus.Okay,
+ statuses.AzimuthAbsoluteEncoderStatus == SensorNetworkSensorStatus.Okay
+ };
+
+ int errors = 0; // TODO: implement conversion (issue #376)
+
+ return EncodeRawData(dataSize, elAccl, azAccl, cbAccl, rawElTemps, rawAzTemps, rawElEnc, rawAzEnc, sensorStatusBoolArray, errors, connectionTimeStamp);
+ }
+
+ ///
+ /// This will take each RAW data array and add it to its proper location in the byte array
+ ///
+ /// The total size of the byte array we are adding data to.
+ /// Array of RAW elevation accelerometer samples.
+ /// Array of RAW azimuth accelerometer samples.
+ /// Array of RAW counterbalance accelerometer samples.
+ /// Array of RAW elevation temperature samples.
+ /// Array of RAW azimuth temperature samples.
+ /// Array of RAW elevation encoder samples. (Should only ever be a size of 1)
+ /// Array of RAW azimuth encoder samples. (Should only ever be a size of 1)
+ /// The time the sensor network connected to the control room. Used to generate simulated acceleration time captures
+ ///
+ public static byte[] EncodeRawData(uint dataSize, RawAccelerometerData[] elAcclData, RawAccelerometerData[] azAcclData, RawAccelerometerData[] cbAcclData, short[] elTemp, short[] azTemp, short[] elEnc, short[] azEnc, bool[] statuses, int errors, long connectionTimeStamp)
+ {
+ byte[] data = new byte[dataSize];
+
+ int i = 0;
+ data[i++] = SensorNetworkConstants.TransitIdSuccess;
+
+ // Store the total data size in 4 bytes
+ Add32BitValueToByteArray(ref data, ref i, dataSize);
+
+ // Store the sensor statuses
+ data[i++] = ConvertBoolArrayToByte(statuses);
+
+ // Store the sensor errors in 3 bytes
+ Add24BitValueToByteArray(ref data, ref i, errors);
+
+ // Store the number of elevation accelerometer fifo dumps in 2 bytes
+ Add16BitValueToByteArray(ref data, ref i, (short)Math.Ceiling(elAcclData.Length * 1.0 / SensorNetworkConstants.ElAccelFIFOSize));
+
+ // Store the number of azimuth accelerometer fifo dumps in 2 bytes
+ Add16BitValueToByteArray(ref data, ref i, (short)Math.Ceiling(azAcclData.Length * 1.0 / SensorNetworkConstants.AzAccelFIFOSize));
+
+ // Store the number of counterbalance accelerometer fifo dumps in 2 bytes
+ Add16BitValueToByteArray(ref data, ref i, (short)Math.Ceiling(cbAcclData.Length * 1.0 / SensorNetworkConstants.CbAccelFIFOSize));
+
+ // Store elevation temperature size in 2 bytes
+ Add16BitValueToByteArray(ref data, ref i, (short)elTemp.Length);
+
+ // Store azimuth temperature size in 2 bytes
+ Add16BitValueToByteArray(ref data, ref i, (short)azTemp.Length);
+
+ // Store elevation encoder size in 2 bytes
+ Add16BitValueToByteArray(ref data, ref i, (short)elEnc.Length);
+
+ // Store azimuth encoder size in 2 bytes
+ Add16BitValueToByteArray(ref data, ref i, (short)azEnc.Length);
+
+ // Store elevation accelerometer data in a variable number of bytes
+ AddAcclDataToByteArray(ref data, ref i, ref elAcclData, SensorNetworkConstants.ElAccelFIFOSize, connectionTimeStamp);
+
+ // Store azimuth accelerometer data in a variable number of bytes
+ AddAcclDataToByteArray(ref data, ref i, ref azAcclData, SensorNetworkConstants.AzAccelFIFOSize, connectionTimeStamp);
+
+ // Store counterbalance accelerometer data in a variable number of bytes
+ AddAcclDataToByteArray(ref data, ref i, ref cbAcclData, SensorNetworkConstants.CbAccelFIFOSize, connectionTimeStamp);
+
+ // Store elevation temperature data in a variable number of bytes
+ // Each temperature occupies 2 bytes
+ for (uint j = 0; j < elTemp.Length; j++)
+ {
+ Add16BitValueToByteArray(ref data, ref i, (short)elTemp[j]);
+ }
+
+ // Store azimuth temperature data in a variable number of bytes
+ // Each temperature occupies 2 bytes
+ for (uint j = 0; j < azTemp.Length; j++)
+ {
+ Add16BitValueToByteArray(ref data, ref i, (short)azTemp[j]);
+ }
+
+ // Store elevation encoder data in a variable number of bytes
+ // Each position occupies 2 bytes
+ for (uint j = 0; j < elEnc.Length; j++)
+ {
+ Add16BitValueToByteArray(ref data, ref i, (short)elEnc[j]);
+ }
+
+ // Store azimuth encoder data in a variable number of bytes
+ // Each position occupies 2 bytes
+ for (uint j = 0; j < azEnc.Length; j++)
+ {
+ Add16BitValueToByteArray(ref data, ref i, (short)azEnc[j]);
+ }
+
+ return data;
+ }
+
+ ///
+ /// Calculates the size of the packet that will be sent to the sensor network.
+ /// This value will be used to create the byte array.
+ ///
+ /// The number of elevation accelerometer samples.
+ /// The number of azimuth accelerometer samples.
+ /// The number of counterbalance accelerometer samples.
+ /// The number of elevation temperature samples.
+ /// The number of azimuth temperature samples.
+ /// The number of elevation encoder samples.
+ /// The number of azimuth encoder samples.
+ ///
+ public static uint CalcDataSize(int elAccSize, int azAccSize, int cbAccSize, int elTempSize, int azTempSize, int elEncSize, int azEncSize)
+ {
+ // 1 for the transmit ID
+ // 4 for the total data size
+ // 4 for the sensor statuses and errors
+ // 14 for each sensor's data size (each sensor size is 2 bytes, with 7 sensors total)
+ uint length = 1 + 4 + 4 + 14;
+
+ // Each accelerometer axis is 2 bytes each. With three axes, that's 6 bytes per accelerometer
+ length += (uint)elAccSize * 6;
+ length += (uint)azAccSize * 6;
+ length += (uint)cbAccSize * 6;
+
+ // Each accelerometer dump has a timestamp associated with it of 8 bytes
+ length += (uint)Math.Ceiling(elAccSize * 1.0 / SensorNetworkConstants.ElAccelFIFOSize) * 8;
+ length += (uint)Math.Ceiling(azAccSize * 1.0 / SensorNetworkConstants.AzAccelFIFOSize) * 8;
+ length += (uint)Math.Ceiling(cbAccSize * 1.0 / SensorNetworkConstants.CbAccelFIFOSize) * 8;
+
+ // Each acceleromter dump has a dump size associated with it that takes up 2 bytes
+ length += (uint)Math.Ceiling(elAccSize * 1.0 / SensorNetworkConstants.ElAccelFIFOSize) * 2;
+ length += (uint)Math.Ceiling(azAccSize * 1.0 / SensorNetworkConstants.AzAccelFIFOSize) * 2;
+ length += (uint)Math.Ceiling(cbAccSize * 1.0 / SensorNetworkConstants.CbAccelFIFOSize) * 2;
+
+ // Each temp and encoder value is 2 bytes
+ length += (uint)elTempSize * 2;
+ length += (uint)azTempSize * 2;
+
+ // Encoder arrays should always be of size 1, so they should only ever be two bytes each
+ length += (uint)elEncSize * 2;
+ length += (uint)azEncSize * 2;
+
+ return length;
+ }
+
+ ///
+ /// This is so we can give the simulation "real" data, where it will be converted to raw
+ /// before being encoded. This is approximate, and may not be exact.
+ ///
+ /// The data we are converting to a raw elevation position.
+ /// The raw elevation position.
+ public static short ConvertDegreesToRawElData(double dataToConvert)
+ {
+ return (short)Math.Round((dataToConvert - 104.375) / -0.25);
+ }
+
+ ///
+ /// This is so we can give the simulation "real" data, where it will be converted to raw
+ /// before being encoded. This is approximate, and may not be exact.
+ ///
+ /// The data we are converting to a raw azimuth position.
+ /// The raw elevation position
+ public static short ConvertDegreesToRawAzData(double dataToConvert)
+ {
+ return (short)((SensorNetworkConstants.AzimuthEncoderScaling * dataToConvert / 360) * -1);
+ }
+
+ ///
+ /// This converts the degrees from celsius into raw data. This is approximate.
+ ///
+ /// The data we are converting to a raw value (in Celsius)
+ /// Raw temperature data.
+ public static short ConvertTempCToRawData(double dataToConvert)
+ {
+ return (short)(dataToConvert * 16);
+ }
+
+ ///
+ /// A helper function to add 16-bit values to the byte array so we don't have to do this every single time.
+ ///
+ /// The byte array we are modifying.
+ /// The counter to tell us where in the byte array we are modifying.
+ /// The data we are adding to the byte array.
+ public static void Add16BitValueToByteArray(ref byte[] dataToAddTo, ref int counter, short dataBeingAdded)
+ {
+ dataToAddTo[counter++] = (byte)((((short)dataBeingAdded) & 0xFF00) >> 8);
+ dataToAddTo[counter++] = (byte)((((short)dataBeingAdded & 0x00FF)));
+ }
+
+ ///
+ /// A helper function to add 24-bit values to the byte array so we don't have to do this every single time.
+ ///
+ /// The byte array we are modifying.
+ /// The counter to tell us where in the byte array we are modifying.
+ /// The data we are adding to the byte array.
+ public static void Add24BitValueToByteArray(ref byte[] dataToAddTo, ref int counter, int dataBeingAdded)
+ {
+ dataToAddTo[counter++] = (byte)((((short)dataBeingAdded) & 0xFF0000) >> 16);
+ dataToAddTo[counter++] = (byte)((((short)dataBeingAdded) & 0x00FF00) >> 8);
+ dataToAddTo[counter++] = (byte)((short)dataBeingAdded & 0x0000FF);
+ }
+
+ ///
+ /// A helper function to add 32-bit values to the byte array so we don't have to do this every single time.
+ ///
+ /// The byte array we are modifying.
+ /// The counter to tell us where in the byte array we are modifying.
+ /// The data we are adding to the byte array.
+ public static void Add32BitValueToByteArray(ref byte[] dataToAddTo, ref int counter, uint dataBeingAdded)
+ {
+ dataToAddTo[counter++] = (byte)((dataBeingAdded & 0xFF000000) >> 24);
+ dataToAddTo[counter++] = (byte)((dataBeingAdded & 0x00FF0000) >> 16);
+ dataToAddTo[counter++] = (byte)((dataBeingAdded & 0x0000FF00) >> 8);
+ dataToAddTo[counter++] = (byte)(dataBeingAdded & 0x000000FF);
+ }
+
+ ///
+ /// A helper function to add 64-bit values to the byte array so we don't have to do this every single time.
+ ///
+ /// The byte array we are modifying.
+ /// The counter to tell us where in the byte array we are modifying.
+ /// The data we are adding to the byte array.
+ public static void Add64BitValueToByteArray(ref byte[] dataToAddTo, ref int counter, ulong dataBeingAdded)
+ {
+ Add32BitValueToByteArray(ref dataToAddTo, ref counter, (uint)((dataBeingAdded & 0xFFFFFFFF00000000) >> 32));
+ Add32BitValueToByteArray(ref dataToAddTo, ref counter, (uint)(dataBeingAdded & 0x00000000FFFFFFFF));
+ }
+
+
+ private static byte ConvertBoolArrayToByte(bool[] source)
+ {
+ if (source.Length > 8) throw new ArgumentOutOfRangeException("There can only be 8 bits in a byte array.");
+
+ byte result = 0;
+
+ int index = 8 - source.Length;
+
+ // Loop through the array
+ foreach (bool b in source)
+ {
+ // if the element is 'true' set the bit at that position
+ if (b)
+ result |= (byte)(1 << (7 - index));
+
+ index++;
+ }
+
+ return result;
+ }
+
+ ///
+ /// A helper function to add acceleration data to the byte array so we don't have to do this every single time.
+ ///
+ /// The byte array we are modifying
+ /// The counter to tell us where in the byte array we are modifying.
+ /// The raw acceleration data we are adding.
+ /// The size of the FIFO for the accelerometer.
+ /// The UTC ms time that the sensor network connected to the control room.
+ private static void AddAcclDataToByteArray(ref byte[] dataToAddTo, ref int counter, ref RawAccelerometerData[] accl, short fifoSize, long connectionTimeStamp)
+ {
+ double totalNumDumps = Math.Ceiling(accl.Length * 1.0 / fifoSize);
+
+ // Process and encode each fifo dump into the array
+ for (int dumpNum = 0; dumpNum < totalNumDumps; dumpNum++)
+ {
+ // Add a generated timestamp, apply a offset to simulate time passing, and account for the connection time
+ Add64BitValueToByteArray(ref dataToAddTo, ref counter, (ulong)(DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() + (50 * dumpNum) - connectionTimeStamp));
+
+ // Set default dump size
+ short dumpSize = fifoSize;
+
+ // Calculate the base index to take from the accl array
+ int baseIndex = dumpNum * fifoSize;
+
+ // Change the dump size to be the remaining data size left if there is not a full dump available
+ if (baseIndex + fifoSize > accl.Length)
+ {
+ dumpSize = (short)(accl.Length - (dumpNum * fifoSize));
+ }
+
+ // Add dump size
+ Add16BitValueToByteArray(ref dataToAddTo, ref counter, dumpSize);
+
+ // Each axis occupies 2 bytes, making a total of 6 bytes for each accelerometer data
+ for (int j = baseIndex; j < baseIndex + dumpSize; j++)
+ {
+ Add16BitValueToByteArray(ref dataToAddTo, ref counter, (short)accl[j].X);
+ Add16BitValueToByteArray(ref dataToAddTo, ref counter, (short)accl[j].Y);
+ Add16BitValueToByteArray(ref dataToAddTo, ref counter, (short)accl[j].Z);
+ }
+ }
+ }
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Simulation/RawAccelerometerData.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Simulation/RawAccelerometerData.cs
new file mode 100644
index 00000000..610f2624
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Simulation/RawAccelerometerData.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ControlRoomApplication.Controllers.SensorNetwork
+{
+ ///
+ /// This is used to store SimulationSensorNetwork accelerometer data.
+ /// Because the raw data we get from the Sensor Network only contains
+ /// x, y and z data, in order to make the simulation as similar
+ /// to the real Sensor Network as possible, we are making this separate
+ /// from our Acceleration class, which contains extra fields.
+ ///
+ public struct RawAccelerometerData
+ {
+ ///
+ /// Accelerometer x-axis data.
+ ///
+ public int X { get; set; }
+
+ ///
+ /// Accelerometer y-axis data.
+ ///
+ public int Y { get; set; }
+
+ ///
+ /// Accelerometer z-axis data.
+ ///
+ public int Z { get; set; }
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Simulation/SensorStatuses.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Simulation/SensorStatuses.cs
new file mode 100644
index 00000000..4639376f
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Simulation/SensorStatuses.cs
@@ -0,0 +1,60 @@
+using ControlRoomApplication.Entities.DiagnosticData;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ControlRoomApplication.Controllers.SensorNetwork.Simulation
+{
+ ///
+ /// This contains all of the sensor statuses for the Sensor Network.
+ ///
+ public class SensorStatuses // TODO: Add errors here (issue #353)
+ {
+ ///
+ /// The error state of the azimuth absolute encoder.
+ ///
+ public SensorNetworkSensorStatus AzimuthAbsoluteEncoderStatus { get; set; }
+
+ ///
+ /// The error state of the elevation absolute encoder.
+ ///
+ public SensorNetworkSensorStatus ElevationAbsoluteEncoderStatus { get; set; }
+
+ ///
+ /// The error state of the azimuth temperature sensor.
+ ///
+ public SensorNetworkSensorStatus AzimuthTemperature1Status { get; set; }
+
+ ///
+ /// The error state of the redundant azimuth temperature sensor.
+ ///
+ public SensorNetworkSensorStatus AzimuthTemperature2Status { get; set; }
+
+ ///
+ /// The error state of the elevation temperature sensor.
+ ///
+ public SensorNetworkSensorStatus ElevationTemperature1Status { get; set; }
+
+ ///
+ /// The error state of the redundant elevation temperature sensor.
+ ///
+ public SensorNetworkSensorStatus ElevationTemperature2Status { get; set; }
+
+ ///
+ /// The error state of the azimuth accelerometer status.
+ ///
+ public SensorNetworkSensorStatus AzimuthAccelerometerStatus { get; set; }
+
+ ///
+ /// The error state of the elevation accelerometer status.
+ ///
+ public SensorNetworkSensorStatus ElevationAccelerometerStatus { get; set; }
+
+ ///
+ /// The error state of the counterbalance accelerometer status.
+ ///
+ public SensorNetworkSensorStatus CounterbalanceAccelerometerStatus { get; set; }
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Simulation/SimulationCSVData/TestAzAccX.csv b/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Simulation/SimulationCSVData/TestAzAccX.csv
new file mode 100644
index 00000000..7b056e80
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Simulation/SimulationCSVData/TestAzAccX.csv
@@ -0,0 +1 @@
+17,17,15,14,12,11,9,9,8,8,8,6,5,5,7,8,10,10,11,13,14,14,14,12,12,11,11,11,11,11,11,13,12,12,11,11,9,9,10,10,10,10,11,13,13,13,11,11,12,13,15,17,19,20,20,22,21,19,18,16,15,13,12,12,13,14,16,16,17,19,19,18,17,17,16,15,15,16,16,18,18,18,17,16,14,13,11,11,9,9,10,11,11,12,13,14,16,16,15,14,14,14,14,14,14,16,18,18,17,16,14,13,14,15,15,16,14,14,13,11,10,8,8,8,9,11,11,11,12,14,14,15,15,15,15,14,13,12,11,10,10,10,10,11,12,12,14,15,15,16,16,16,15,13,12,10,9,9,9,9,11,11,12,14,15,17,17,17,16,15,13,12,10,11,12,14,15,17,17,17,16,15,15,15,17,18,18,18,18,18,16,16,16,17,18,21,22,24,25,26,27,28,27,26,25,23,22,21,20,18,17,16,14,13,11,11,9,9,9,9,9,10,12,13,13,15,18,21,23,25,26,26,26,26,25,25,24,22,21,19,18,16,15,15,15,15,17,18,20,21,23,25,26,28,28,28,28,27,25,24,24,22,21,19,17,16,13,11,10,8,8,8,8,8,9,10,12,12,13,14,16,17,18,19,21,22,22,22,20,18,18,17,15,14,13,13,13,13,13,14,17,17,20,21,23,24,26,26,26,25,24,22,22,21,19,18,16,16,17,18,19,20,21,22,24,26,27,27,27,27,25,24,22,20,19,17,18,20,21,23,25,26,26,26,25,25,24,22,21,19,18,16,17,19,19,20,22,22,22,22,22,21,21,20,18,17,18,19,21,22,22,23,24,24,24,24,22,22,20,19,17,17,17,18,20,21,23,24,26,25,25,25,24,22,22,21,20,20,19,17,17,16,16,16,16,16,16,18,19,21,23,24,26,27,27,27,27,27,27,27,22,21,19,18,16,16,15,15,13,14,14,14,18,19,21,23,26,28,29,28,28,28,27,26,25,23,22,21,19,18,16,14,14,14,14,14,16,18,19,20,21,21,21,21,21,21,19,18,16,15,15,15,15,15,15,17,18,20,20,20,20,19,18,16,14,13,13,12,12,12,12,12,12,14,16,17,19,20,22,24,24,24,24,21,21,19,18,16,15,12,11,10,8,8,7,7,7,7,7,7,9,11,15,15,16,19,20,21,23,23,23,23,23,22,20,19,17,16,14,13,13,11,11,11,11,11,13,14,14,17,19,20,21,21,21,21,21,21,21,19,18,16,16,16,17,18,21,23,23,23,23,23,22,22,20,18,16,14,13,13,13,15,18,21,23,25,28,29,29,28,26,23,21,20,18,17,15,14,14,14,16,17,18,19,21,23,24,24,24,24,23,22,22,17,15,12,9,9,8,7,7,7,7,7,9,10,10,12,13,15,17,18,18,18,16,16,14,13,12,10,9,8,8,7,7,7,7,9,11,13,13,15,16,20,21,23,23,25,25,25,25,24,22,20,17,13,11,10,9,9,9,9,9,9,9,9,11,11,12,15,16,18,19,21,21,22,23,23,23,22,20,18,15,14,13,10,10,8,8,8,8,8,8,9,10,10,11,12,16,17,17,19,21,21,22,22,22,20,20,17,15,13,10,9,9,9,9,9,9,11,13,17,17,19,22,26,27,29,30,30,30,30,28,26,23,23,19,16,14,12,10,10,10,10,12,15,17,18,20,21,23,24,24,24,24,24,22,20,18,17,15,14,12,12,12,10,10,11,13,15,16,18,20,21,23,24,26,27,27,27,26,25,27,28,31,32,34,36,37,39,39,39,36,33,27,23,19,15,14,12,11,13,14,16,18,21,22,23,24,26,25,26,26,27,28,29,31,32,33,33,32,31,28,25,24,20,18,17,17,17,19,19,20,22,24,25,26,27,28,30,30,30,30,29,28,26,24,21,19,17,16,14,13,13,15,15,19,21,25,30,32,35,36,37,39,38,34,31,29,25,22,15,13,11,12,14,15,15,18,20,21,19,18,16,15,15,15,16,17,19,21,23,24,27,28,29,29,29,29,29,28,27,27,26,24,22,21,19,19,19,20,20,22,23,25,27,28,30,29,29,26,23,21,20,18,17,15,13,12,12,12,13,14,16,19,20,23,27,28,30,33,35,37,38,38,37,36,34,31,29,27,25,24,22,21,21,21,21,21,21,24,27,29,31,34,37,38,40,41,41,41,41,39,37,36,34,31,26,25,23,22,22,22,26,28,31,33,36,42,45,46,46,48,48,47,46,43,42,38,36,35,32,30,29,27,26,26,26,26,26,26,26,28,32,33,36,40,41,44,45,45,47,47,47,46,44,43,39,37,35,33,32,30,29,27,27,27,27,27,27,29,29,31,30,29,27,24,22,20,18,17,17,17,17,17,17,17,18,19,19,19,18,16,15,13,11,10,10,10,10,12,13,15,16,18,18,17,16,16,14,12,11,9,9,9,9,9,10,10,12,16,18,19,21,23,24,25,26,28,27,23,23,20,18,17,16,14,14,14,14,15,16,18,20,21,21,21,21,21,20,18,17,14,13,10,9,7,7,6,6,4,4,5,6,8,10,11,11,13,16,19,21,22,23,24,24,24,23,22,20,19,17,16,14,14,14,15,17,18,18,20,24,25,26,28,28,27,26,24,22,18,17,15,14,12,12,12,13,13,14,17,19,20,21,25,26,28,29,29,29,29,27,25,23,22,20,19,17,17,17,17,17,17,17,19,20,21,23,25,26,26,26,25,25,23,22,20,18,17,15,15,15,18,20,22,25,26,28,28,28,28,28,28,27,26,24,23,21,20,18,19,20,20,24,26,29,31,32,34,35,34,31,30,26,23,22,20,19,18,18,18,18,22,24,26,27,29,30,32,32,32,32,32,30,29,27,25,24,23,21,20,20,20,21,22,24,26,27,29,30,32,32,32,32,32,31,30,28,26,25,23,23,23,24,25,25,28,30,31,33,36,37,37,39,38,37,35,33,31,29,26,25,24,23,21,21,21,22,22,24,26,27,28,29,29,29,29,29,28,26,26,25,23,21,20,20,20,20,20,20,20,22,24,25,27,28,28,28,27,26,23,20,19,15,14,12,13,17,17,20,20,22,24,26,27,27,27,26,24,24,22,22,21,19,18,16,16,17,18,20,22,24,25,27,28,30,30,29,27,26,25,23,20,19,19,19,24,26,28,29,31,32,34,34,33,31,28,26,24,22,21,19,18,18,18,19,22,24,25,26,27,28,28,27,27,23,19,18,17,15,15,15,15,17,21,23,24,26,28,27,27,25,25,24,21,20,19,17,16,16,16,18,21,24,24,27,29,30,30,30,29,29,25,25,24,22,21,19,19,19,19,19,20,20,22,23,27,28,30,30,29,29,27,26,22,20,18,17,15,14,12,12,12,12,12,13,13,14,17,19,21,25,26,30,30,30,29,28,26,25,23,21,20,20,18,18,18,18,19,21,22,23,24,25,27,27,27,27,27,27,24,24,20,18,17,14,13,11,11,11,11,11,11,12,12,12,12,13,15,16,18,19,19,19,19,19,19,19,17,15,13,11,10,9,7,7,7,7,7,7,7,8,9,11,14,14,16,18,20,21,21,21,21,19,16,15,13,11,10,9,9,8,8,7,7,8,10,10,16,18,20,22,24,26,28,27,27,25,23,19,15,13,11,9,9,7,7,7,7,7,8,11,11,15,17,21,22,26,28,31,32,32,30,29,27,25,22,21,20,18,17,17,17,17,17,17,17,18,21,23,24,26,27,27,26,22,19,17,13,10,8,8,6,6,6,6,7,9,11,11,11,14,17,19,21,22,22,22,22,20,18,17,15,13,12,12,13,14,15,18,20,21,23,27,28,28,28,28,28,25,25,22,20,19,17,16,14,13,13,11,11,11,11,12,12,16,17,19,21,24,26,27,27,27,26,25,21,19,15,11,9,6,6,6,6,8,11,12,12,16,17,19,21,23,22,22,20,19,15,13,13,12,10,10,11,10,11,13,15,18,20,22,23,25,25,22,20,19,17,15,14,12,12,13,14,14,16,17,17,16,14,12,12,10,8,7,7,7,7,7,7,9,12,14,16,16,18,20,21,21,19,18,14,12,10,7,7,6,4,4,2,2,2,2,2,3,3,3,4,7,8,9,11,11,11,11,8,8,7,7,5,4,4,4,6,7,7,9,11,12,12,14,14,14,12,10,8,5,5,3,1,-1,-1,-1,-2,-2,-2,0,2,2,4,5,7,9,12,14,14,17,18,18,18,16,14,11,10,7,7,3,3,2,0,0,1,3,4,7,9,12,16,16,17,19,20,22,23,23,23,20,18,16,13,11,10,9,9,8,8,8,8,9,11,12,12,14,17,19,21,25,26,28,30,31,31,30,28,24,21,19,15,13,10,8,7,7,5,6,8,11,11,13,17,19,21,25,27,30,31,33,34,34,33,32,30,26,24,22,19,17,15,14,14,13,13,15,17,19,20,24,25,28,30,32,32,29,27,23,20,18,16,15,13,13,14,14,15,17,19,21,22,24,27,29,32,34,34,35,36,37,37,37,36,36,34,31,30,28,25,24,22,21,21,21,22,27,29,32,35,39,43,46,49,51,52,53,55,56,56,56,56,56,55,54,53,51,50,52,55,57,61,64,67,68,70,70,68,65,63,59,58,56,53,53,52,50,50,50,51,52,56,60,64,68,77,83,86,87,89,90,92,91,86,85,81,79,78,77,75,75,74,75,76,79,81,83,87,89,92,95,96,99,97,96,94,92,91,88,86,84,82,79,78,76,75,73,72,69,66,65,65,65,65,66,66,68,69,70,69,69,66,64,62,60,57,54,52,50,49,48,47,46,46,44,45,45,46,46,44,41,40,38,35,34,32,31,29,30,32,32,33,35,36,36,32,30,28,26,23,22,20,19,19,19,19,19,19,21,23,25,26,27,28,25,23,23,22,20,19,19,19,22,25,27,29,30,32,33,31,28,25,24,22,20,19,17,17,19,20,23,25,28,30,32,34,35,37,36,33,33,31,27,26,23,21,19,19,20,22,23,25,29,31,33,36,37,39,40,42,42,42,42,41,40,38,34,32,28,27,25,24,24,24,24,24,24,27,31,33,36,38,41,46,49,50,52,52,52,49,48,44,42,41,37,35,34,34,34,36,38,40,44,45,47,49,52,54,54,53,51,49,46,45,41,39,38,36,34,34,35,35,39,41,43,44,48,51,54,58,62,65,67,68,68,67,66,63,59,56,52,49,47,44,43,42,41,41,39,37,37,36,37,38,38,39,39,39,39,36,33,32,30,30,29,29,29,31,33,34,36,37,36,34,31,29,25,23,22,20,19,17,18,19,21,23,23,25,28,30,31,33,32,29,27,24,20,17,15,12,10,9,9,9,11,12,12,14,17,19,21,25,25,26,26,26,26,25,22,19,16,15,14,13,12,13,13,14,14,16,18,19,22,24,26,26,26,26,26,25,23,23,19,18,16,15,15,15,17,19,20,23,25,28,30,33,35,34,34,32,30,27,25,23,19,18,16,14,13,14,15,15,17,19,21,22,24,25,27,27,27,26,23,20,17,15,13,11,10,9,9,10,10,11,12,13,16,16,19,21,21,21,21,21,20,18,17,16,15,13,12,12,12,12,12,12,13,15,19,21,23,26,28,29,27,25,23,21,17,16,14,10,9,7,7,6,6,6,6,7,7,10,10,12,16,17,19,20,22,23,23,23,23,23,21,18,15,14,9,8,6,6,5,5,5,6,6,6,10,13,13,17,21,21,25,26,28,28,28,27,25,23,20,18,17,14,12,10,10,10,10,11,11,14,16,18,20,22,23,25,26,26,26,25,23,20,18,15,11,10,7,7,6,4,5,5,5,7,9,13,13,14,18,20,23,25,26,28,28,28,27,27,25,21,20,16,14,12,10,9,9,10,10,10,12,12,13,15,18,20,22,24,26,27,28,27,27,27,24,20,18,16,13,11,10,10,10,11,13,14,15,18,22,26,28,32,35,38,38,39,39,36,32,27,23,21,17,15,14,14,14,14,15,17,18,20,22,26,27,29,32,34,36,36,36,35,33,31,29,26,23,21,19,17,16,15,14,13,13,13,13,15,17,20,21,24,25,27,29,32,34,35,35,35,35,33,30,27,25,24,22,21,21,23,26,29,30,33,36,37,39,40,40,37,35,32,29,27,26,24,22,23,23,23,22,22,20,19,19,19,21,25,26,27,29,29,29,29,29,31,32,32,32,31,30,26,24,23,21,20,20,20,22,23,25,27,28,30,31,33,32,32,31,29,28,28,26,24,24,24,25,27,28,32,32,34,35,34,32,31,30,29,27,25,25,25,26,28,30,31,33,31,28,27,24,21,19,18,16,15,15,15,17,19,20,23,24,25,27,28,25,24,20,17,15,13,11,11,11,11,11,12,13,14,15,15,16,17,18,18,18,16,14,13,11,10,10,10,12,14,16,17,19,20,22,22,21,19,18,15,12,11,9,8,8,8,8,8,10,12,12,15,18,19,23,25,26,27,28,27,24,22,16,13,11,7,6,6,4,3,3,7,9,11,15,15,18,22,22,26,27,27,26,24,19,16,12,8,7,7,5,3,2,2,4,4,6,8,11,13,13,15,18,19,20,21,23,23,23,23,22,20,18,16,11,8,6,6,5,3,2,2,2,3,5,8,12,12,15,17,20,23,25,26,27,27,25,23,21,18,15,14,11,10,8,8,8,8,8,9,10,11,11,14,17,18,20,20,20,20,17,14,11,9,9,7,6,6,8,9,9,11,12,12,14,14,14,14,12,11,11,11
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Simulation/SimulationCSVData/TestAzAccY.csv b/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Simulation/SimulationCSVData/TestAzAccY.csv
new file mode 100644
index 00000000..a799b292
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Simulation/SimulationCSVData/TestAzAccY.csv
@@ -0,0 +1 @@
+-2,-1,-1,-1,-3,-3,-3,-2,2,2,3,5,5,6,6,4,3,1,0,-2,-2,-4,-6,-7,-8,-10,-10,-10,-7,-7,-6,-3,-1,0,0,2,2,1,-1,-1,-2,-3,-4,-5,-7,-7,-6,-5,-3,-1,0,0,2,3,5,5,5,4,3,1,-1,-2,-2,-4,-5,-5,-5,-4,-4,-3,-1,1,2,2,4,5,5,7,6,5,4,3,0,-1,-1,-3,-3,-3,-2,-2,0,0,0,1,3,3,2,2,1,-2,-3,-3,-4,-6,-7,-9,-9,-8,-8,-6,-5,-3,-2,-1,0,0,0,0,0,0,-1,-1,-2,-2,-5,-8,-9,-10,-11,-11,-11,-11,-10,-8,-7,-4,-1,2,5,5,7,7,6,5,5,2,-1,-1,-2,-4,-5,-7,-7,-7,-7,-6,-4,-3,1,1,3,4,4,4,4,3,3,1,0,-1,-1,-3,-3,-2,0,0,1,1,1,0,0,-1,-2,-2,-3,-4,-5,-5,-5,-5,-5,-3,0,0,2,4,5,7,8,8,8,8,6,5,3,1,0,-2,-2,-2,-2,-2,-2,-1,1,2,2,4,5,5,5,4,3,1,0,-3,-4,-4,-6,-7,-8,-8,-9,-9,-9,-11,-10,-10,-9,-7,-6,-6,-5,-3,-2,-1,0,0,0,0,0,-3,-3,-4,-5,-7,-8,-10,-10,-10,-12,-12,-12,-12,-12,-11,-9,-8,-8,-6,-4,-3,-1,0,2,2,3,3,3,1,0,-1,-2,-4,-4,-4,-5,-6,-6,-6,-6,-6,-4,-3,-1,1,1,2,4,5,7,8,8,8,6,5,4,3,-1,-1,-2,-4,-5,-6,-7,-6,-6,-4,-3,-1,2,3,3,4,5,7,7,7,6,5,5,3,1,0,0,0,0,3,6,8,11,11,12,14,14,13,13,12,10,9,9,7,5,5,5,4,4,4,5,6,10,12,12,13,14,15,16,16,16,16,15,12,11,9,8,6,5,5,5,5,5,5,5,7,8,10,11,11,12,12,13,15,15,15,15,14,14,12,10,10,9,6,6,5,4,2,2,2,2,3,4,7,9,11,11,13,14,14,16,16,15,15,13,12,11,9,9,7,5,4,4,4,4,5,6,8,10,11,11,13,14,14,14,14,13,11,10,8,6,6,3,2,2,2,0,0,0,1,2,4,5,7,7,7,7,6,4,3,3,1,-1,-1,-1,-1,-1,0,0,2,4,5,7,9,10,10,12,13,15,15,14,13,13,11,7,5,5,4,2,1,-1,-1,-3,-3,-3,-3,-2,0,3,3,8,8,11,13,13,14,14,14,14,13,11,9,9,6,3,1,0,-1,-1,-2,-2,-2,-1,-1,0,0,3,5,7,9,8,7,5,3,2,0,-2,-2,-3,-3,-3,-1,1,1,2,3,4,5,5,5,4,2,0,-4,-4,-6,-6,-6,-6,-3,0,0,3,4,6,7,9,10,10,10,8,8,6,4,0,-2,-5,-8,-10,-10,-10,-10,-10,-10,-9,-9,-7,-6,-4,-2,0,1,1,2,2,2,2,0,-1,-1,-3,-5,-6,-8,-8,-8,-7,-5,-4,-2,-1,1,3,3,4,6,7,7,7,7,7,5,2,1,-1,-3,-3,-5,-5,-4,-3,0,0,1,5,7,8,10,10,11,13,12,12,10,7,5,3,2,-1,-2,-2,-4,-6,-6,-6,-6,-6,-6,-4,-2,-1,1,1,1,2,2,2,2,0,-3,-3,-4,-6,-7,-9,-10,-10,-7,-7,-5,-3,0,2,5,7,11,12,14,14,14,14,13,13,11,10,8,6,6,5,3,3,4,5,8,9,11,11,12,14,16,17,15,13,12,10,10,9,9,9,9,11,12,12,14,15,15,15,15,15,13,12,11,10,9,9,7,8,9,11,11,15,18,22,24,28,29,31,31,30,26,24,23,21,19,17,16,15,13,13,14,16,17,19,21,22,24,24,25,25,24,23,22,20,18,16,13,12,10,10,11,11,12,14,14,13,11,8,8,7,5,4,6,6,8,12,12,13,13,12,9,9,7,6,2,0,0,1,1,4,5,6,6,4,4,0,-1,-5,-5,-7,-9,-10,-11,-13,-13,-13,-12,-10,-9,-7,-7,-5,-4,-2,-1,-1,-3,-5,-8,-10,-12,-12,-14,-15,-17,-17,-16,-15,-14,-12,-11,-9,-9,-8,-8,-8,-8,-8,-11,-11,-14,-16,-17,-19,-18,-17,-15,-13,-13,-16,-16,-18,-20,-23,-24,-24,-26,-25,-24,-19,-17,-16,-12,-11,-9,-7,-7,-5,-7,-7,-9,-12,-13,-13,-16,-18,-19,-19,-19,-17,-15,-14,-11,-9,-9,-8,-6,-5,-4,-4,-5,-6,-7,-11,-11,-11,-12,-14,-16,-16,-15,-13,-12,-10,-7,-7,-5,-4,-4,-4,-6,-8,-10,-11,-11,-12,-15,-16,-15,-14,-11,-10,-8,-7,-7,-5,-3,-2,0,0,0,-1,-1,-1,-3,-3,-4,-7,-10,-10,-12,-14,-15,-17,-18,-18,-17,-17,-14,-12,-8,-5,-5,-5,-3,0,2,2,4,4,3,3,1,0,-2,-4,-5,-5,-7,-9,-9,-10,-10,-10,-8,-8,-8,-7,-5,-5,-3,-1,0,0,-2,-4,-4,-5,-7,-10,-12,-12,-14,-15,-15,-15,-15,-8,-8,-5,-3,-1,0,2,1,1,-1,-1,-1,-3,-4,-7,-10,-10,-11,-11,-11,-11,-11,-11,-10,-10,-9,-7,-6,-6,-4,-4,-4,-2,-2,-2,-3,-5,-7,-9,-10,-12,-13,-13,-15,-15,-14,-13,-10,-8,-6,-6,-4,-2,2,3,3,5,5,5,5,4,2,0,-4,-4,-7,-9,-11,-12,-12,-12,-14,-14,-14,-14,-14,-14,-13,-11,-10,-8,-8,-6,-5,-2,0,2,2,3,5,5,6,6,6,6,6,6,6,5,3,2,-1,-1,-1,-3,-4,-6,-7,-9,-10,-10,-12,-14,-14,-14,-14,-13,-11,-10,-8,-6,-6,-5,-3,-2,0,0,1,3,5,5,5,5,5,4,2,0,-1,-1,-3,-5,-6,-8,-9,-11,-11,-11,-12,-14,-15,-15,-17,-17,-17,-17,-17,-17,-17,-15,-15,-11,-9,-7,-7,-4,-2,-1,1,1,2,2,3,3,3,3,3,3,2,0,-3,-3,-4,-4,-6,-7,-9,-9,-10,-10,-10,-10,-10,-10,-10,-10,-9,-8,-8,-6,-3,-1,0,2,2,3,3,3,3,3,3,1,-1,-1,-2,-4,-5,-5,-7,-9,-10,-10,-10,-10,-10,-10,-10,-9,-7,-7,-1,1,3,3,3,3,3,1,-1,-2,-2,-4,-5,-5,-5,-4,-3,0,0,3,4,6,7,7,7,5,4,1,-1,-4,-4,-6,-8,-9,-11,-11,-11,-10,-6,-6,-4,3,6,6,10,13,13,15,16,16,13,11,9,9,5,4,0,-3,-3,-5,-4,-1,1,1,6,10,10,13,15,16,18,17,15,13,9,6,6,3,1,-3,-4,-4,-4,-4,0,0,2,4,7,8,10,12,12,11,7,7,6,2,-1,-4,-4,-5,-7,-5,-4,-3,1,3,4,4,6,5,3,2,0,-4,-5,-5,-7,-8,-10,-10,-9,-8,-8,-5,-4,-2,-1,1,2,2,5,6,7,6,5,2,-2,-2,-4,-5,-7,-9,-10,-12,-13,-13,-15,-17,-17,-18,-18,-19,-20,-22,-22,-22,-22,-22,-21,-19,-18,-17,-13,-12,-8,-8,-7,-5,-4,-2,0,0,0,1,3,4,4,6,7,7,7,8,9,9,9,9,8,8,8,8,6,5,3,3,1,1,0,0,-2,-2,-3,-5,-6,-7,-8,-9,-11,-11,-12,-12,-14,-14,-15,-15,-15,-15,-15,-15,-15,-15,-15,-13,-12,-12,-10,-9,-9,-9,-9,-7,-5,-4,-3,-2,-1,1,2,2,4,5,5,7,8,10,10,12,12,12,12,12,12,12,11,11,11,9,9,8,6,5,5,3,2,1,0,-1,-1,-3,-4,-5,-6,-7,-9,-10,-10,-12,-14,-14,-15,-15,-15,-15,-15,-15,-15,-15,-14,-13,-13,-12,-11,-11,-10,-8,-8,-8,-6,-5,-4,-3,-2,0,0,1,2,3,4,5,7,7,7,7,7,6,6,5,3,1,0,-1,-2,-2,-3,-5,-6,-8,-9,-10,-10,-11,-12,-13,-15,-16,-16,-18,-18,-20,-20,-21,-21,-23,-23,-23,-22,-21,-20,-17,-16,-13,-11,-9,-9,-8,-6,-5,-4,-2,-1,0,0,1,2,4,4,4,4,4,4,4,3,3,2,2,1,0,-1,-3,-3,-5,-6,-6,-9,-11,-11,-12,-14,-16,-17,-19,-20,-22,-23,-23,-25,-25,-26,-26,-26,-26,-26,-24,-23,-22,-21,-20,-18,-16,-15,-13,-10,-7,-6,-3,-3,-2,-2,0,0,2,2,2,2,2,2,1,-1,-2,-4,-6,-7,-9,-11,-11,-12,-14,-13,-11,-8,-7,-7,-4,-3,-1,1,1,2,4,3,3,2,2,0,0,-2,-2,-3,-5,-6,-8,-8,-8,-8,-8,-8,-8,-7,-6,-4,-3,-1,0,3,4,5,7,7,7,6,6,4,4,3,2,0,-2,-2,-3,-4,-6,-7,-7,-7,-7,-7,-5,-3,-2,1,1,6,7,9,10,10,10,11,12,13,13,13,13,13,13,11,9,9,9,8,6,5,3,3,4,4,6,9,13,15,15,17,20,21,23,22,20,19,17,15,14,12,10,9,9,8,6,5,5,3,3,3,3,3,3,3,3,3,4,4,5,6,7,8,10,10,9,9,7,6,4,3,1,0,0,0,0,0,0,2,4,5,7,8,10,11,11,11,9,9,8,6,5,3,3,2,2,2,2,2,2,4,4,5,7,8,10,10,11,13,13,13,13,13,13,13,12,10,9,7,7,5,4,2,-1,-1,-3,-4,-4,-4,-6,-6,-6,-6,-5,-4,-4,-3,-1,1,3,3,3,4,6,7,9,10,12,12,13,13,15,15,14,12,12,10,7,5,4,2,0,-1,-1,-3,-4,-5,-6,-7,-7,-7,-7,-6,-5,-3,-4,-5,-8,-10,-13,-13,-15,-16,-18,-19,-19,-19,-19,-19,-19,-19,-19,-19,-19,-19,-19,-17,-15,-14,-12,-11,-9,-9,-9,-9,-10,-10,-11,-11,-12,-14,-16,-17,-17,-17,-17,-17,-17,-17,-17,-17,-17,-16,-15,-13,-12,-10,-9,-7,-7,-6,-4,-4,-2,-2,-1,-1,-1,-1,-1,-1,-3,-6,-8,-9,-12,-13,-14,-15,-16,-18,-19,-19,-21,-21,-21,-21,-21,-21,-21,-21,-20,-19,-17,-15,-14,-14,-12,-11,-9,-9,-9,-9,-8,-6,-6,-5,-5,-7,-8,-9,-10,-13,-13,-15,-16,-20,-21,-22,-22,-22,-22,-22,-22,-22,-21,-19,-19,-18,-16,-15,-13,-11,-10,-6,-5,-3,-3,-2,-1,0,1,1,3,3,3,2,2,-1,-3,-3,-7,-9,-13,-14,-14,-17,-20,-22,-24,-25,-25,-27,-29,-29,-29,-29,-29,-28,-27,-27,-25,-23,-22,-19,-18,-15,-14,-11,-9,-6,-6,-6,-5,-4,-4,-4,-4,-4,-4,-4,-6,-9,-10,-12,-12,-17,-19,-21,-23,-24,-26,-27,-29,-30,-32,-34,-34,-34,-34,-34,-34,-34,-33,-33,-31,-30,-27,-25,-24,-23,-21,-20,-19,-15,-13,-10,-9,-8,-8,-8,-7,-7,-7,-7,-9,-11,-13,-13,-15,-17,-20,-23,-24,-26,-30,-31,-33,-35,-36,-38,-38,-38,-38,-38,-37,-37,-36,-34,-30,-29,-27,-22,-20,-10,-9,-7,-7,-7,-7,-6,-6,-8,-10,-10,-13,-17,-19,-21,-25,-26,-29,-30,-31,-31,-33,-32,-32,-32,-30,-28,-27,-24,-24,-22,-20,-17,-16,-14,-11,-10,-10,-10,-10,-10,-10,-10,-12,-13,-13,-15,-17,-18,-20,-21,-22,-23,-23,-23,-23,-23,-22,-20,-19,-17,-11,-9,-9,-3,-2,0,0,1,1,1,1,-1,-4,-4,-5,-8,-10,-11,-11,-15,-17,-18,-18,-18,-18,-17,-15,-13,-10,-9,-7,-7,-5,-4,-4,-4,-5,-6,-8,-10,-12,-13,-13,-16,-17,-20,-22,-22,-23,-23,-23,-23,-23,-23,-22,-21,-19,-16,-15,-11,-9,-7,-7,-5,-4,-2,-1,-1,-1,1,1,1,0,-1,-1,-3,-6,-8,-11,-11,-13,-15,-18,-20,-21,-22,-23,-23,-23,-23,-23,-23,-22,-21,-19,-17,-16,-14,-12,-11,-7,-7,-6,-4,-5,-7,-9,-11,-11,-13,-14,-16,-17,-19,-20,-22,-24,-27,-29,-31,-33,-33,-36,-37,-39,-39,-39,-39,-39,-39,-38,-37,-35,-33,-32,-32,-32,-32,-34,-36,-38,-40,-41,-42,-44,-45,-45,-45,-45,-44,-43,-42,-39,-38,-35,-32,-31,-29,-28,-26,-26,-25,-25,-24,-23,-24,-24,-24,-23,-22,-18,-16,-11,-6,-5,-5,-1,0,0,0,0,-1,-1,-2,-3,-5,-5,-6,-8,-7,-7,-5,-4,-3,1,2,4,4,5,5,5,1,-1,-1,-2,-4,-6,-7,-9,-9,-8,-8,-8,-6,-5,-3,-2,-1,0,0,0,-1,-2,-4,-4,-5,-7,-10,-10,-11,-12,-14,-15,-17,-18,-18,-20,-20,-20,-20,-20,-20,-19,-19,-18,-18,-16,-14,-13,-11,-10,-8,-7,-5,-5,-3,-2,-1,0,0,0,0,0,-1,-4,-4,-5,-9,-12,-12,-15,-16,-19,-20,-22,-24,-25,-25,-25,-25,-25,-23,-23,-20,-18,-17,-16,-14,-13,-11,-10,-10,-10,-10,-10,-10,-12,-14,-18,-20,-24,-26,-30,-32,-33,-35,-36,-37,-37,-37,-37,-37,-36,-35,-33,-31,-26,-24,-21,-19,-17,-15,-14,-14,-14,-14,-15,-17,-21,-22,-25,-32,-34,-36,-37,-39,-40,-40,-40,-40,-40,-40,-40,-38,-36,-34,-33,-31,-29,-26,-22,-21,-19,-17,-17,-17,-17,-17,-18,-20,-24,-25,-27,-31,-33,-33,-35,-38,-39,-40,-41,-41,-41,-42,-42,-42,-42,-41,-40,-38,-36,-35,-33,-31,-30,-28,-25,-23,-23,-21,-20,-20,-18,-18,-18,-18,-20,-22,-23,-25,-29,-30,-33,-35,-36,-38,-39,-41,-42,-44,-44,-45,-45,-45,-45,-45,-45,-45,-43,-39,-35,-33,-29,-25,-22,-18,-13,-9,-9,-9,-8,-6,-5,-5,-5,-5,-5,-5,-6,-7,-11,-11,-13,-15,-19,-20,-23,-26,-27,-30,-32,-32,-32,-33,-34,-35,-37,-37,-37,-37,-37,-37,-34,-32,-31,-28,-26,-25,-23,-21,-18,-17,-16,-14,-14,-13,-13,-11,-9,-9,-9,-10,-10,-12,-13,-15,-18,-21,-24,-26,-27,-30,-32,-33,-36,-38,-38,-38,-38,-39,-41,-41,-41,-40,-40,-39,-39,-37,-35,-32,-30,-29,-27,-26,-24,-22,-21,-20,-19,-19,-19,-19,-19,-19,-19,-21,-22,-25,-27,-29,-31,-34,-36,-37,-39,-41,-42,-42,-44,-44,-44,-44,-44,-43,-43,-39,-38,-36,-34,-32,-27,-24,-22,-20,-18,-17,-15,-13,-12,-11,-9,-9,-9,-9,-9,-9,-9,-9,-10,-10,-11,-13,-16,-19,-23,-24,-27,-29,-31,-32,-33,-34,-35,-35,-35,-35,-35,-34,-33,-31,-29,-28,-26,-25,-24,-20,-19,-17,-15,-14,-13,-11,-11,-10,-10,-8,-8,-8,-9,-9,-9,-10,-11,-11,-15,-16,-20,-22,-23,-25,-26,-28,-29,-31,-31,-32,-32,-32,-32,-32,-32,-32,-32,-30,-28,-27,-25,-24,-20,-17,-14,-10,-9,-9,-8,-8,-6,-6,-5,-5,-5,-5,-6,-9,-13,-13,-14,-17,-21,-23,-27,-28,-31,-31,-32,-33,-33,-32,-32,-32,-30,-26,-24,-21,-18,-14,-11,-7,-5,-5,-6,-6,-8,-9,-11,-11,-12,-12,-12,-12,-13,-16,-20,-22,-29,-30,-33,-35,-35,-34,-34,-33,-30,-29,-24,-22,-20,-19,-17,-16,-16,-16,-17,-18,-19,-21,-23,-24,-24,-24,-23,-23,-19,-16,-16,-14,-13,-14,-17,-18,-19,-20,-22,-23,-25,-25,-26,-28,-28,-28,-28,-27,-27,-27,-26,-24,-22,-20,-17,-16,-14,-13,-11,-11,-9,-9,-9,-9,-9,-9,-9,-10,-12,-12,-13
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Simulation/SimulationCSVData/TestAzAccZ.csv b/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Simulation/SimulationCSVData/TestAzAccZ.csv
new file mode 100644
index 00000000..4e5f1c8d
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Simulation/SimulationCSVData/TestAzAccZ.csv
@@ -0,0 +1 @@
+-194,-190,-187,-182,-180,-177,-177,-175,-174,-176,-178,-179,-181,-183,-184,-186,-188,-189,-191,-192,-192,-192,-192,-189,-184,-183,-181,-180,-180,-180,-180,-180,-182,-183,-185,-185,-185,-185,-184,-183,-181,-180,-180,-180,-182,-183,-187,-188,-189,-189,-188,-186,-185,-184,-183,-182,-182,-182,-180,-180,-178,-179,-179,-179,-181,-182,-184,-185,-185,-187,-187,-187,-185,-185,-183,-183,-182,-180,-179,-179,-179,-179,-179,-179,-180,-182,-184,-185,-185,-187,-189,-190,-190,-190,-190,-188,-187,-186,-185,-183,-183,-182,-182,-182,-181,-180,-180,-181,-183,-184,-186,-187,-189,-189,-189,-189,-189,-189,-188,-187,-185,-185,-183,-183,-183,-183,-183,-183,-183,-184,-185,-185,-185,-185,-185,-183,-181,-181,-181,-182,-184,-184,-185,-187,-187,-189,-189,-189,-189,-189,-187,-185,-184,-183,-182,-181,-179,-179,-179,-179,-179,-181,-183,-183,-184,-184,-184,-184,-182,-181,-179,-177,-176,-176,-176,-176,-176,-178,-180,-180,-183,-184,-184,-186,-186,-188,-188,-188,-188,-188,-188,-187,-185,-184,-182,-182,-181,-181,-181,-181,-181,-181,-183,-184,-186,-188,-189,-191,-192,-194,-194,-194,-196,-196,-196,-196,-195,-193,-192,-190,-188,-187,-186,-185,-184,-183,-181,-181,-179,-179,-179,-180,-180,-180,-184,-185,-188,-190,-191,-192,-193,-194,-194,-196,-196,-196,-196,-196,-195,-192,-191,-189,-188,-186,-185,-185,-185,-185,-185,-185,-185,-186,-188,-190,-190,-190,-191,-191,-191,-191,-189,-187,-186,-186,-186,-184,-183,-183,-182,-181,-181,-181,-181,-181,-181,-183,-184,-186,-187,-187,-189,-189,-188,-188,-187,-185,-184,-182,-181,-179,-179,-177,-177,-177,-177,-177,-178,-179,-181,-182,-183,-184,-185,-185,-185,-185,-183,-181,-180,-179,-177,-175,-174,-172,-172,-172,-170,-170,-170,-171,-172,-175,-176,-180,-181,-183,-184,-185,-187,-187,-187,-187,-189,-189,-189,-189,-189,-189,-187,-185,-184,-182,-180,-179,-178,-177,-177,-177,-177,-177,-178,-179,-181,-182,-184,-185,-186,-187,-189,-189,-189,-189,-189,-188,-188,-187,-185,-184,-183,-182,-181,-179,-179,-180,-180,-181,-183,-183,-184,-184,-184,-182,-180,-179,-178,-176,-176,-176,-176,-176,-177,-178,-179,-179,-181,-181,-181,-183,-183,-183,-183,-183,-182,-182,-181,-179,-177,-177,-177,-175,-175,-175,-175,-176,-176,-176,-178,-179,-181,-181,-182,-183,-184,-184,-185,-185,-183,-182,-180,-179,-177,-176,-176,-174,-172,-172,-172,-172,-172,-173,-173,-174,-176,-179,-181,-185,-187,-187,-188,-188,-188,-188,-187,-185,-181,-178,-176,-174,-172,-171,-169,-167,-167,-165,-165,-165,-165,-166,-170,-172,-173,-174,-175,-176,-178,-179,-181,-181,-183,-185,-185,-185,-184,-182,-181,-179,-177,-176,-174,-173,-171,-170,-170,-170,-170,-170,-172,-173,-174,-175,-175,-176,-176,-176,-176,-176,-175,-176,-178,-179,-181,-181,-182,-183,-183,-183,-181,-180,-178,-179,-180,-181,-182,-183,-183,-183,-183,-181,-180,-179,-178,-177,-175,-175,-174,-174,-174,-174,-176,-178,-180,-182,-184,-187,-188,-190,-192,-193,-195,-197,-197,-197,-196,-193,-190,-189,-187,-186,-184,-183,-181,-180,-180,-180,-180,-180,-180,-180,-182,-184,-184,-184,-184,-184,-184,-183,-181,-180,-178,-177,-175,-175,-175,-175,-176,-177,-178,-179,-180,-182,-184,-185,-187,-188,-189,-190,-191,-191,-191,-190,-189,-188,-185,-184,-182,-180,-179,-178,-176,-175,-175,-174,-173,-173,-174,-175,-176,-177,-178,-179,-180,-182,-182,-182,-182,-181,-179,-178,-176,-175,-173,-172,-172,-172,-172,-172,-172,-172,-172,-174,-176,-177,-179,-179,-181,-181,-181,-181,-181,-180,-178,-177,-175,-173,-173,-172,-172,-172,-172,-172,-173,-174,-176,-177,-179,-180,-182,-182,-184,-185,-187,-188,-189,-189,-189,-189,-186,-184,-184,-181,-179,-178,-176,-175,-173,-173,-173,-173,-173,-174,-174,-175,-175,-177,-177,-178,-179,-180,-181,-181,-181,-183,-183,-183,-183,-181,-179,-178,-177,-175,-173,-173,-171,-171,-171,-171,-172,-172,-174,-175,-177,-177,-179,-180,-182,-184,-185,-187,-187,-189,-189,-189,-189,-189,-188,-187,-185,-182,-181,-180,-179,-177,-175,-175,-175,-175,-175,-175,-175,-175,-178,-180,-182,-183,-185,-186,-188,-190,-190,-191,-191,-191,-191,-190,-189,-187,-185,-184,-181,-179,-178,-177,-176,-176,-176,-176,-176,-176,-177,-178,-180,-181,-183,-184,-186,-187,-187,-187,-187,-184,-182,-180,-178,-176,-175,-173,-173,-174,-176,-177,-178,-180,-182,-183,-185,-185,-187,-187,-187,-187,-187,-187,-187,-186,-184,-181,-180,-178,-176,-175,-175,-175,-175,-175,-175,-175,-176,-177,-179,-180,-180,-182,-182,-182,-182,-182,-182,-181,-180,-178,-175,-172,-171,-170,-170,-170,-168,-168,-169,-171,-175,-176,-178,-179,-181,-182,-184,-185,-187,-187,-187,-187,-187,-186,-183,-182,-178,-177,-175,-175,-173,-173,-173,-173,-173,-173,-174,-177,-179,-182,-183,-185,-186,-187,-188,-189,-189,-191,-191,-191,-190,-188,-184,-181,-179,-176,-174,-173,-173,-173,-173,-173,-174,-174,-176,-177,-178,-180,-181,-183,-185,-185,-185,-184,-182,-180,-179,-178,-177,-176,-174,-174,-174,-174,-174,-174,-174,-175,-176,-176,-176,-176,-176,-176,-174,-173,-171,-170,-169,-169,-169,-170,-171,-172,-172,-173,-174,-175,-174,-173,-170,-168,-167,-167,-167,-169,-170,-171,-172,-174,-174,-174,-174,-172,-170,-169,-167,-166,-165,-165,-167,-169,-170,-172,-173,-174,-175,-177,-178,-180,-180,-182,-182,-182,-182,-182,-180,-177,-174,-172,-171,-171,-170,-168,-166,-166,-165,-165,-165,-165,-167,-169,-169,-170,-172,-173,-173,-175,-177,-177,-178,-179,-180,-180,-180,-180,-178,-174,-172,-171,-168,-166,-165,-163,-163,-162,-161,-161,-161,-161,-161,-161,-162,-166,-168,-169,-171,-172,-176,-176,-178,-179,-182,-183,-185,-187,-187,-187,-187,-187,-186,-185,-183,-181,-179,-176,-175,-173,-172,-170,-170,-168,-166,-166,-166,-166,-166,-167,-168,-171,-174,-175,-177,-178,-181,-184,-188,-189,-191,-193,-195,-195,-195,-195,-192,-191,-187,-186,-183,-181,-179,-177,-177,-175,-175,-175,-175,-175,-175,-177,-180,-181,-183,-184,-186,-188,-188,-189,-189,-189,-189,-187,-185,-184,-183,-181,-179,-179,-179,-179,-180,-181,-183,-184,-186,-186,-188,-188,-188,-188,-187,-185,-184,-182,-181,-179,-178,-178,-176,-176,-176,-176,-176,-177,-178,-178,-180,-181,-183,-183,-183,-183,-183,-183,-183,-182,-181,-178,-176,-174,-172,-170,-168,-166,-166,-164,-164,-164,-165,-166,-167,-168,-170,-171,-173,-173,-175,-176,-177,-176,-175,-174,-171,-170,-166,-164,-163,-161,-161,-161,-161,-161,-162,-164,-166,-170,-172,-173,-176,-178,-179,-179,-179,-179,-178,-176,-175,-173,-169,-168,-167,-166,-165,-165,-163,-163,-163,-164,-165,-167,-169,-173,-174,-176,-177,-179,-179,-180,-182,-183,-184,-184,-183,-182,-180,-177,-176,-175,-173,-172,-170,-170,-169,-169,-167,-167,-167,-167,-167,-168,-169,-171,-173,-174,-176,-176,-178,-178,-179,-179,-179,-179,-178,-177,-175,-174,-172,-170,-169,-168,-166,-166,-164,-164,-164,-164,-164,-164,-165,-167,-169,-170,-172,-173,-175,-176,-178,-178,-178,-178,-177,-176,-172,-169,-167,-163,-162,-162,-160,-159,-161,-162,-163,-164,-165,-167,-166,-164,-164,-160,-157,-156,-155,-153,-152,-152,-152,-152,-154,-157,-159,-160,-162,-164,-164,-164,-165,-165,-165,-165,-165,-165,-164,-163,-161,-160,-158,-157,-155,-154,-152,-150,-150,-150,-149,-149,-149,-149,-149,-150,-151,-153,-155,-156,-158,-160,-161,-163,-163,-164,-165,-165,-166,-167,-167,-166,-166,-164,-162,-160,-158,-155,-153,-152,-150,-150,-149,-149,-147,-147,-145,-145,-145,-145,-146,-146,-147,-149,-150,-152,-153,-155,-157,-157,-157,-157,-157,-156,-155,-153,-151,-150,-150,-148,-148,-148,-148,-148,-148,-149,-150,-151,-154,-155,-157,-158,-158,-160,-162,-162,-162,-162,-162,-161,-160,-158,-156,-155,-153,-152,-150,-149,-147,-147,-146,-144,-144,-144,-142,-142,-143,-143,-145,-147,-148,-148,-150,-151,-152,-153,-154,-155,-156,-157,-157,-157,-159,-159,-159,-157,-157,-158,-160,-161,-162,-164,-165,-167,-169,-169,-169,-169,-168,-167,-167,-165,-164,-163,-162,-161,-160,-159,-159,-159,-159,-159,-159,-159,-160,-161,-163,-164,-166,-167,-169,-171,-172,-174,-176,-177,-179,-179,-179,-179,-179,-179,-179,-179,-179,-178,-178,-177,-177,-177,-177,-178,-178,-179,-179,-181,-182,-182,-182,-182,-182,-182,-182,-182,-180,-179,-177,-176,-176,-174,-173,-173,-171,-171,-171,-171,-171,-172,-172,-174,-175,-176,-178,-179,-181,-181,-181,-181,-181,-180,-179,-177,-176,-175,-174,-173,-171,-170,-170,-168,-168,-168,-168,-168,-168,-168,-168,-169,-170,-170,-172,-174,-175,-176,-177,-177,-178,-180,-180,-180,-180,-179,-179,-178,-177,-174,-172,-171,-169,-167,-166,-165,-163,-161,-161,-160,-160,-160,-160,-160,-160,-162,-164,-165,-167,-169,-170,-171,-173,-173,-175,-175,-175,-175,-175,-174,-174,-173,-173,-171,-170,-168,-168,-166,-165,-165,-165,-165,-165,-165,-165,-165,-167,-169,-170,-172,-174,-174,-174,-175,-175,-177,-177,-177,-177,-177,-177,-177,-176,-175,-171,-169,-168,-166,-164,-163,-161,-161,-161,-161,-161,-161,-161,-162,-162,-164,-165,-166,-168,-168,-168,-169,-169,-169,-169,-169,-169,-169,-167,-167,-166,-166,-164,-164,-164,-164,-164,-164,-165,-166,-168,-169,-171,-172,-174,-175,-178,-179,-181,-182,-183,-185,-185,-185,-185,-185,-185,-185,-183,-180,-178,-178,-178,-178,-178,-178,-178,-178,-179,-179,-179,-179,-179,-178,-178,-178,-179,-180,-182,-182,-182,-182,-182,-181,-180,-178,-176,-175,-174,-172,-172,-170,-170,-170,-170,-170,-171,-169,-167,-165,-162,-159,-157,-156,-154,-154,-153,-152,-151,-151,-151,-151,-153,-156,-158,-159,-160,-161,-163,-163,-163,-163,-162,-159,-158,-156,-155,-155,-153,-153,-151,-151,-150,-150,-150,-150,-150,-151,-153,-155,-156,-158,-160,-161,-161,-163,-163,-163,-161,-159,-158,-156,-155,-154,-153,-153,-152,-152,-152,-152,-154,-155,-156,-157,-159,-160,-162,-162,-162,-162,-162,-161,-160,-160,-160,-158,-158,-157,-157,-155,-154,-152,-152,-150,-150,-150,-149,-147,-146,-142,-140,-139,-135,-133,-132,-130,-129,-127,-125,-123,-119,-117,-116,-114,-113,-113,-113,-111,-111,-110,-107,-105,-101,-97,-94,-94,-92,-90,-89,-86,-85,-84,-82,-81,-79,-79,-78,-78,-76,-76,-76,-76,-76,-76,-76,-76,-76,-76,-76,-76,-76,-76,-76,-76,-74,-73,-71,-71,-70,-70,-70,-70,-70,-70,-71,-71,-71,-72,-73,-75,-77,-78,-80,-83,-84,-84,-85,-86,-86,-86,-86,-86,-85,-83,-82,-80,-76,-75,-71,-69,-68,-66,-65,-63,-62,-60,-59,-59,-59,-59,-60,-61,-62,-65,-67,-71,-72,-74,-76,-77,-79,-80,-82,-83,-83,-85,-86,-86,-86,-86,-86,-86,-86,-86,-86,-84,-83,-81,-80,-79,-78,-77,-77,-77,-75,-75,-74,-74,-74,-74,-75,-76,-78,-79,-81,-83,-86,-89,-91,-91,-92,-92,-94,-94,-94,-94,-94,-94,-91,-90,-88,-82,-81,-79,-77,-77,-76,-74,-74,-73,-73,-73,-73,-74,-74,-77,-79,-81,-82,-83,-85,-87,-88,-88,-90,-90,-91,-92,-92,-92,-91,-90,-87,-87,-85,-84,-83,-81,-80,-80,-80,-80,-80,-80,-80,-81,-81,-82,-84,-85,-85,-85,-85,-85,-85,-83,-82,-80,-79,-79,-79,-79,-79,-81,-82,-84,-87,-88,-89,-90,-92,-92,-93,-93,-93,-93,-93,-95,-95,-97,-97,-98,-98,-98,-98,-97,-97,-96,-96,-96,-96,-96,-97,-97,-101,-101,-101,-104,-106,-107,-109,-111,-112,-115,-116,-118,-120,-122,-125,-127,-129,-131,-133,-133,-134,-134,-135,-137,-138,-138,-140,-142,-142,-143,-145,-147,-148,-150,-151,-153,-154,-156,-157,-160,-161,-162,-164,-164,-165,-167,-167,-168,-170,-171,-172,-173,-174,-176,-177,-177,-177,-177,-177,-177,-177,-177,-173,-172,-170,-169,-167,-167,-167,-167,-167,-167,-168,-169,-170,-171,-173,-175,-175,-174,-172,-172,-170,-169,-168,-168,-166,-166,-166,-166,-167,-168,-168,-168,-170,-172,-172,-172,-171,-170,-169,-168,-167,-167,-165,-164,-164,-162,-162,-162,-161,-159,-157,-156,-156,-156,-156,-157,-157,-156,-156,-154,-152,-151,-151,-151,-151,-151,-151,-151,-149,-147,-147,-147,-147,-148,-148,-150,-152,-153,-153,-153,-153,-151,-150,-148,-147,-145,-145,-143,-143,-143,-142,-142,-142,-142,-142,-144,-146,-147,-149,-150,-150,-152,-154,-154,-154,-152,-150,-146,-144,-143,-141,-139,-138,-136,-134,-134,-134,-134,-134,-134,-135,-138,-139,-142,-143,-145,-146,-147,-148,-149,-151,-151,-152,-152,-152,-152,-150,-149,-147,-147,-147,-148,-148,-150,-151,-153,-154,-156,-157,-159,-161,-162,-164,-164,-164,-163,-161,-159,-157,-156,-153,-151,-150,-150,-151,-153,-154,-155,-157,-158,-160,-161,-163,-164,-165,-165,-165,-165,-164,-162,-161,-158,-157,-154,-152,-152,-152,-152,-154,-155,-157,-159,-161,-162,-164,-166,-167,-169,-170,-170,-172,-174,-174,-174,-174,-174,-174,-173,-173,-172,-170,-167,-165,-163,-162,-162,-160,-160,-160,-161,-163,-165,-167,-169,-171,-177,-179,-180,-182,-184,-188,-189,-189,-191,-191,-191,-191,-191,-188,-186,-179,-175,-173,-172,-170,-170,-170,-169,-169,-169,-169,-169,-169,-169,-169,-169,-169,-169,-169,-171,-171,-172,-172,-172,-172,-172,-172,-172,-171,-168,-167,-165,-162,-160,-159,-157,-155,-154,-154,-154,-154,-154,-154,-155,-158,-160,-164,-164,-167,-169,-170,-171,-172,-174,-177,-177,-178,-180,-180,-180,-180,-179,-177,-176,-174,-171,-168,-164,-162,-160,-158,-158,-158,-158,-157,-157,-157,-157,-159,-161,-163,-166,-167,-170,-172,-175,-176,-177,-179,-180,-182,-182,-184,-184,-186,-186,-186,-186,-185,-185,-183,-181,-180,-176,-174,-171,-169,-168,-166,-164,-164,-163,-161,-161,-161,-161,-161,-161,-163,-166,-167,-169,-171,-172,-174,-175,-177,-179,-181,-181,-181,-181,-181,-181,-181,-179,-178,-177,-174,-173,-172,-169,-169,-167,-166,-165,-164,-163,-161,-161,-159,-159,-160,-160,-162,-165,-166,-169,-170,-176,-178,-180,-181,-183,-184,-184,-186,-186,-188,-188,-187,-187,-185,-181,-177,-174,-170,-167,-165,-164,-162,-160,-160,-160,-160,-160,-161,-163,-167,-169,-171,-172,-175,-176,-177,-179,-179,-180,-181,-182,-182,-183,-184,-183,-183,-181,-180,-178,-177,-175,-171,-170,-168,-167,-166,-165,-165,-163,-163,-164,-166,-168,-170,-172,-174,-175,-176,-177,-179,-181,-182,-185,-186,-188,-190,-190,-191,-191,-191,-191,-191,-189,-186,-181,-177,-173,-170,-167,-166,-165,-164,-163,-163,-162,-161,-161,-161,-162,-165,-167,-170,-172,-175,-176,-178,-180,-183,-185,-185,-187,-187,-187,-186,-184,-183,-180,-177,-176,-174,-173,-173,-171,-171,-171,-174,-174,-176,-179,-180,-184,-185,-188,-189,-190,-192,-194,-195,-196,-197,-197,-196,-195,-191,-188,-186,-182,-181,-179,-178,-177,-176,-176,-176,-176,-176,-176,-176,-178,-180,-182,-184,-186,-187,-189,-190,-191,-192,-192,-193,-194,-195,-195,-195,-195,-193,-191,-189,-187,-185,-184,-182,-181,-179,-177,-176,-176,-174,-174,-174,-174,-174,-174,-174,-177,-180,-181,-183,-186,-187,-189,-190,-191,-193,-194,-195,-196,-196,-196,-196,-195,-192,-187,-183,-178,-174,-171,-167,-165,-163,-162,-162,-162,-162,-162,-162,-164,-166,-167,-169,-171,-172,-174,-175,-177,-177,-177,-177,-177,-176,-172,-169,-164,-163,-160,-158,-157,-157,-157,-157,-158,-159,-161,-161,-163,-165,-166,-168,-170,-171,-172,-174,-175,-175,-175,-177,-177,-177,-177,-177,-177,-174,-172,-170,-166,-165,-163,-162,-160,-159,-159,-157,-157,-157,-157,-157,-158,-161,-162,-165,-167,-169,-171,-172,-173,-175,-176,-177,-178,-179,-179,-181,-181,-181,-181,-180,-177,-174,-171,-169,-168,-166,-166,-164,-164,-163,-161,-159,-159,-157,-157,-157,-157,-157,-157,-158,-160,-162,-164,-165,-166,-168,-169,-171,-171,-173,-173,-173,-173,-173,-172,-171,-169,-168,-166,-166,-166,-166,-166,-167,-168,-170,-172,-175,-175,-176,-176,-176,-176,-175,-174,-172,-171,-172,-172,-173,-175,-176,-178,-179,-179,-179,-179,-179,-179,-177,-174,-172,-170,-168,-168,-168,-168,-168,-169,-171,-172,-172,-174,-176,-177,-178,-180,-182,-183,-185,-185,-185,-184,-183,-181,-180,-179,-178,-177,-176,-174,-173,-171,-169,-169,-169,-168,-168,-168,-168,-168,-169,-169,-170,-170,-172,-172,-173,-175,-176,-176,-178,-178,-179,-181,-181,-182,-182,-182,-184,-184,-184,-185,-185,-185,-185,-185,-183,-183,-182,-180
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Simulation/SimulationCSVData/TestAzEnc.csv b/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Simulation/SimulationCSVData/TestAzEnc.csv
new file mode 100644
index 00000000..aa246d99
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Simulation/SimulationCSVData/TestAzEnc.csv
@@ -0,0 +1 @@
+5,6,8,10,10,13,18,19,24,26,30,30,32,35,37,39,41,44,46,51,55,58,62,64,67,70,72,74,77,81,83,86,88,89,92,102,106,106,112,116,120,123,127,131,134,136,140,143,144,148,151,153,155,158,159,163,165,170,172,174,178,179,183,187,190,193,197,199,204,205,209,211,213,215,216,218,221,222,224,227,229,231,232,233,234,235,238,239,240,242,243,245,246,248,251,253,256,258,260,261,261,263,264,266,267,269,271,271,272,275,277,279,280,282,284,285,287,287,288,290,290,291,293,294,296,297,299,299,300,302,303,305,305,306,307,310,311,313,313,314,314,316,317,317,319,320,320,322,324,325,326,327,328,328,330,330,330,331,333,333,334,335,336,336,337,339,341,342,344,346,346,347,349,350,352,352,353,355,355,356,356,356,356,356,356,356,356,356,355,354,352,351,349,347,346,344,341,339,335,334,331,328,325,323,320,318,315,313,310,307,304,301,299,296,292,291,286,284,278,274,270,268,263,261,256,254,245,241,237,234,232,228,224,218,215,211,206,203,198,193,188,185,180,177,173,169,168,165,163,160,156,154,151,148,145,141,138,135,132,129,125,123,120,118,117,115,114,113,109,107,106,104,102,101,99,99,96,94,93,89,86,85,81,79,76,73,70,67,65,64,62,60,57,54,51,48,45,42,39,37,36,34,32,32,31,29,28,28,26,26,25,24,23,23,22,22,20,20,19,18,17,17,16,14,14,12,12,11,11,11,9,9,9,9,9,9,9,9,10,10,10,10,12,13,13,15,17,18,19,21,23,25,26,28,29,31,33,35,38,39,41,44,46,50,52,55,58,60,62,64,66,70,71,73,76,79,81,84,86,90,93,97,101,103,103,106,109,112,117,118,122,127,131,136,140,144,149,156,159,165,169,173,178,179,183,185,187,191,193,195,200,203,206,210,212,215,218,220,222,224,225,229,232,235,239,242,245,248,250,253,256,259,261,263,266,268,271,273,275,276,278,280,282,285,287,289,293,295,297,298,300,302,304,306,309,312,315,317,321,322,324,326,327,330,331,332,334,335,337,338,340,340,341,343,345,346,347,348,349,351,351,352,352,354,354,354,355,355,355,355,355,355,355,353,353,352,350,350,348,347,347,345,343,342,340,339,337,335,334,334,331,329,328,326,324,322,320,319,318,315,313,311,309,308,306,305,303,301,299,296,294,291,290,287,282,281,277,273,271,268,265,263,260,258,255,252,249,247,242,239,234,231,225,221,218,214,210,206,202,200,197,193,191,188,185,182,177,175,172,169,167,164,160,157,155,151,149,145,143,139,135,134,130,127,124,119,118,114,110,107,104,98,91,91,83,80,77,72,68,64,63,60,57,54,51,49,49,48,46,45,43,41,40,38,38,37,35,34,33,32,32,31,31,29,29,28,28,26,26,26,24,24,24,24,23,23,23,21,21,21,21,21,21,21,21,21,21,21,21,21,21,22,22,22,22,22,23,23,24,25,26,28,29,32,34,35,37,39,41,46,47,50,51,53,54,56,57,59,61,62,63,66,67,70,71,72,74,75,78,79,82,87,90,93,95,97,100,102,102,107,110,112,116,119,122,127,129,138,141,143,146,148,151,154,157,159,162,167,169,171,173,176,178,181,183,186,187,191,194,195,199,201,205,209,211,215,217,221,224,228,231,233,236,241,243,246,248,249,252,254,255,256,257,258,261,263,265,265,267,269,270,271,274,276,278,280,281,283,284,285,287,289,291,292,294,295,297,298,300,302,302,303,304,305,307,309,311,312,314,316,317,319,321,324,326,327,329,330,332,333,334,335,336,338,339,341,343,344,344,346,347,348,349,349,350,350,352,352,352,352,352,352,352,352,352,351,351,351,350,350,348,346,346,345,343,341,340,338,337,335,332,331,330,328,326,323,321,320,318,315,314,312,311,310,308,307,307,305,304,302,300,299,298,296,295,293,291,290,289,287,285,284,282,278,276,271,269,267,264,260,258,254,250,244,240,237,229,224,221,216,212,206,203,200,194,191,187,184,180,177,174,171,168,165,161,157,154,151,147,145,141,139,136,132,129,126,123,122,118,116,114,109,106,105,101,97,97,94,91,88,84,80,79,75,74,68,65,63,61,59,57,56,54,52,50,49,47,45,44,44,42,42,41,39,38,36,34,33,31,29,28,28,27,26,25,23,23,23,22,22,20,18,18,17,17,15,15,14,14,14,12,12,10,9,9,9,7,6,6,6,5,4
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Simulation/SimulationCSVData/TestAzTemp.csv b/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Simulation/SimulationCSVData/TestAzTemp.csv
new file mode 100644
index 00000000..15df29f1
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Simulation/SimulationCSVData/TestAzTemp.csv
@@ -0,0 +1 @@
+27,27,27,27,27,27,25,25,25,25,25,25,25,25,25,25,24,24,24,24,22,22,22,22,22,21,21,21,21,21,21,20,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,20,20,20,20,20,20,21,21,21,21,23,23,23,23,23,23,25,25,25,25,25,26,26,26,26,26,28,28,28,28,28,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,30,30,30,30,30,30,30,30,30,29,29,29,29,29,27,27,27,27,25,25,25,25,25,25,25,25,25,24,24,24,24,24,24,24,24,24,24,24,24,24,24,22,22,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,17,17,17,17,18,18,20,20,20,22,22,22,22,23,23,25,25,25,27,27,27,27,27,27,28,28,28,28,28,28,28,28,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,29,29,29,29,29
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Simulation/SimulationCSVData/TestCbAccX.csv b/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Simulation/SimulationCSVData/TestCbAccX.csv
new file mode 100644
index 00000000..48e51869
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Simulation/SimulationCSVData/TestCbAccX.csv
@@ -0,0 +1 @@
+-36,-37,-37,-38,-38,-38,-40,-40,-41,-42,-42,-42,-42,-42,-42,-40,-39,-38,-38,-36,-36,-36,-36,-37,-38,-40,-42,-43,-44,-45,-46,-48,-48,-47,-46,-44,-42,-39,-36,-35,-33,-31,-30,-28,-25,-25,-25,-25,-25,-25,-25,-25,-28,-29,-31,-31,-32,-34,-35,-37,-39,-39,-39,-40,-40,-40,-38,-38,-36,-34,-33,-31,-30,-28,-28,-27,-27,-27,-27,-29,-30,-32,-34,-36,-38,-40,-42,-44,-44,-45,-45,-45,-45,-45,-45,-43,-41,-40,-38,-37,-35,-35,-34,-34,-32,-32,-32,-32,-33,-35,-37,-39,-42,-45,-47,-51,-51,-52,-52,-52,-52,-52,-52,-51,-47,-46,-43,-40,-39,-37,-36,-36,-34,-34,-34,-35,-37,-42,-43,-44,-46,-47,-48,-49,-49,-49,-49,-48,-46,-43,-40,-37,-35,-33,-31,-27,-25,-25,-24,-24,-24,-25,-27,-30,-33,-35,-39,-41,-42,-44,-45,-45,-45,-43,-43,-41,-39,-37,-36,-34,-33,-33,-31,-31,-32,-32,-34,-38,-40,-43,-46,-47,-48,-50,-50,-51,-51,-50,-50,-48,-46,-44,-43,-41,-38,-37,-35,-35,-34,-34,-34,-34,-34,-36,-38,-42,-44,-45,-47,-47,-48,-50,-50,-52,-52,-51,-48,-47,-43,-41,-40,-36,-35,-33,-31,-31,-31,-31,-31,-33,-36,-37,-39,-40,-42,-43,-43,-43,-43,-43,-43,-41,-37,-36,-34,-32,-31,-29,-29,-29,-29,-29,-30,-33,-36,-36,-37,-39,-40,-40,-40,-39,-38,-37,-35,-34,-33,-32,-35,-37,-41,-43,-44,-44,-44,-42,-41,-39,-37,-37,-36,-36,-34,-34,-35,-35,-37,-38,-40,-40,-41,-43,-44,-45,-45,-45,-45,-44,-44,-42,-41,-39,-38,-36,-35,-33,-33,-33,-33,-35,-35,-39,-41,-42,-43,-44,-45,-47,-47,-47,-47,-47,-46,-43,-41,-39,-37,-35,-34,-34,-34,-34,-35,-37,-41,-42,-44,-48,-50,-51,-52,-53,-54,-55,-56,-56,-55,-55,-54,-53,-50,-49,-47,-46,-45,-43,-42,-41,-40,-40,-39,-39,-39,-39,-39,-39,-41,-43,-45,-46,-46,-48,-49,-49,-49,-49,-49,-48,-46,-43,-40,-39,-38,-37,-35,-34,-33,-32,-32,-31,-31,-31,-31,-31,-31,-31,-31,-31,-31,-31,-31,-32,-32,-32,-32,-32,-33,-33,-35,-37,-38,-40,-40,-42,-42,-42,-42,-43,-43,-43,-45,-45,-45,-45,-45,-45,-45,-45,-44,-44,-44,-44,-44,-44,-44,-43,-43,-43,-41,-39,-39,-38,-37,-36,-36,-36,-36,-36,-36,-37,-38,-38,-38,-39,-39,-41,-41,-42,-42,-42,-42,-44,-44,-44,-46,-46,-47,-47,-49,-49,-49,-49,-49,-49,-49,-49,-48,-48,-48,-47,-47,-47,-47,-45,-45,-43,-43,-42,-42,-42,-42,-42,-42,-42,-42,-42,-42,-42,-42,-42,-42,-42,-43,-44,-44,-44,-44,-44,-44,-44,-44,-43,-43,-43,-43,-43,-43,-43,-43,-43,-43,-43,-43,-43,-43,-42,-42,-42,-42,-42,-42,-42,-41,-40,-40,-40,-40,-38,-38,-38,-38,-38,-39,-39,-40,-41,-41,-43,-43,-43,-43,-44,-44,-44,-44,-44,-44,-46,-46,-46,-46,-46,-46,-46,-46,-46,-45,-44,-43,-42,-40,-40,-38,-38,-38,-38,-38,-39,-39,-39,-39,-39,-41,-41,-41,-41,-42,-42,-42,-42,-42,-42,-42,-44,-44,-44,-44,-44,-44,-44,-44,-44,-44,-43,-43,-42,-42,-40,-38,-37,-37,-37,-37,-37,-37,-35,-35,-35,-36,-36,-36,-36,-36,-36,-38,-39,-39,-39,-41,-41,-43,-45,-45,-45,-45,-45,-45,-45,-43,-43,-43,-43,-43,-42,-42,-42,-44,-44,-44,-44,-44,-44,-44,-44,-46,-46,-46,-46,-46,-46,-46,-46,-47,-47,-47,-47,-49,-49,-49,-50,-50,-50,-50,-50,-48,-47,-45,-43,-40,-40,-38,-37,-35,-35,-35,-35,-35,-35,-35,-35,-36,-36,-36,-36,-36,-36,-36,-36,-36,-36,-36,-36,-36,-35,-33,-33,-31,-31,-30,-30,-30,-28,-29,-29,-29,-31,-31,-33,-33,-34,-35,-36,-38,-38,-39,-40,-40,-42,-44,-44,-44,-46,-48,-48,-48,-49,-49,-49,-49,-49,-49,-49,-49,-49,-49,-49,-49,-49,-49,-47,-47,-45,-44,-44,-42,-42,-42,-42,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-39,-39,-39,-39,-39,-39,-39,-39,-39,-39,-39,-39,-39,-40,-41,-41,-41,-41,-41,-41,-41,-41,-41,-41,-41,-41,-41,-41,-41,-41,-41,-41,-41,-41,-41,-43,-44,-44,-46,-46,-46,-46,-46,-46,-46,-46,-46,-46,-46,-46,-46,-46,-45,-44,-43,-42,-40,-39,-39,-37,-37,-35,-35,-34,-34,-34,-33,-32,-32,-32,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-31,-31,-32,-33,-34,-34,-34,-34,-34,-34,-34,-34,-34,-34,-34,-34,-34,-34,-34,-34,-34,-34,-34,-34,-34,-34,-34,-34,-34,-34,-34,-34,-36,-36,-38,-38,-38,-38,-39,-39,-39,-39,-39,-39,-39,-39,-39,-37,-37,-36,-36,-35,-34,-33,-33,-33,-33,-33,-33,-33,-33,-33,-33,-33,-33,-33,-33,-33,-33,-33,-33,-33,-33,-32,-31,-31,-31,-29,-29,-29,-29,-29,-29,-29,-29,-29,-29,-29,-29,-29,-29,-29,-30,-32,-32,-33,-33,-35,-35,-36,-37,-37,-38,-38,-38,-39,-40,-40,-40,-41,-42,-42,-42,-42,-42,-42,-42,-41,-39,-39,-39,-38,-37,-36,-35,-33,-33,-32,-31,-30,-28,-27,-27,-27,-27,-27,-27,-27,-27,-29,-29,-29,-30,-31,-31,-35,-35,-35,-37,-37,-37,-38,-38,-38,-38,-38,-38,-38,-38,-38,-38,-38,-38,-38,-36,-36,-36,-36,-36,-36,-36,-36,-36,-36,-36,-36,-36,-36,-36,-36,-36,-36,-36,-36,-36,-37,-38,-38,-38,-39,-40,-40,-40,-42,-44,-44,-44,-45,-45,-45,-45,-45,-45,-45,-45,-45,-45,-45,-45,-44,-42,-42,-40,-39,-37,-35,-33,-32,-31,-30,-29,-29,-29,-29,-29,-29,-29,-29,-29,-31,-33,-34,-36,-37,-37,-38,-39,-39,-40,-41,-41,-41,-41,-41,-41,-41,-41,-41,-41,-41,-41,-41,-40,-40,-38,-38,-38,-38,-38,-38,-38,-38,-37,-37,-37,-37,-35,-35,-35,-35,-35,-35,-35,-35,-35,-35,-36,-36,-38,-38,-39,-39,-41,-41,-43,-43,-43,-43,-43,-43,-43,-43,-43,-43,-43,-43,-43,-43,-42,-41,-39,-38,-37,-36,-35,-34,-33,-33,-33,-33,-33,-33,-33,-33,-33,-34,-36,-36,-38,-38,-40,-40,-42,-44,-44,-44,-44,-45,-45,-45,-45,-45,-45,-45,-45,-45,-44,-44,-44,-42,-41,-41,-41,-41,-39,-39,-39,-37,-37,-37,-36,-33,-33,-33,-33,-33,-33,-33,-33,-33,-34,-34,-36,-36,-36,-36,-36,-36,-38,-38,-38,-38,-38,-38,-38,-38,-38,-38,-38,-38,-37,-37,-36,-34,-33,-31,-30,-30,-30,-30,-30,-30,-30,-31,-31,-33,-35,-39,-39,-39,-41,-41,-42,-44,-44,-44,-46,-46,-46,-48,-48,-48,-48,-48,-48,-48,-48,-48,-48,-47,-47,-47,-45,-44,-44,-43,-43,-43,-42,-41,-41,-41,-41,-41,-41,-41,-41,-41,-41,-39,-39,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-42,-42,-42,-42,-42,-42,-39,-36,-35,-33,-32,-30,-28,-28,-28,-28,-28,-28,-28,-28,-28,-29,-29,-31,-32,-35,-35,-37,-37,-39,-39,-41,-41,-41,-41,-41,-41,-41,-41,-41,-41,-41,-41,-41,-41,-41,-41,-41,-41,-41,-41,-39,-37,-37,-37,-35,-33,-33,-33,-33,-33,-33,-33,-33,-33,-33,-33,-34,-34,-34,-36,-36,-38,-38,-39,-39,-39,-41,-43,-43,-44,-44,-44,-44,-44,-46,-46,-46,-46,-46,-45,-45,-43,-42,-41,-40,-37,-36,-36,-34,-34,-34,-34,-34,-34,-34,-34,-34,-34,-35,-37,-37,-39,-39,-39,-39,-39,-39,-39,-39,-39,-39,-39,-39,-39,-39,-39,-39,-39,-39,-39,-39,-39,-39,-38,-36,-36,-36,-36,-36,-36,-36,-36,-36,-36,-36,-37,-37,-39,-39,-40,-40,-42,-44,-44,-44,-44,-46,-48,-48,-48,-48,-49,-49,-49,-49,-49,-49,-49,-49,-49,-49,-47,-47,-47,-46,-46,-44,-42,-41,-40,-39,-39,-38,-38,-38,-38,-38,-38,-38,-38,-38,-40,-40,-42,-43,-45,-45,-46,-49,-49,-49,-51,-52,-53,-53,-53,-53,-53,-53,-53,-53,-53,-53,-53,-53,-53,-53,-53,-53,-53,-53,-53,-52,-52,-52,-52,-53,-50,-49,-47,-45,-44,-43,-43,-43,-43,-41,-41,-41,-41,-41,-40,-40,-40,-40,-40,-40,-40,-42,-42,-44,-44,-44,-44,-44,-44,-45,-45,-45,-45,-45,-47,-47,-47,-47,-47,-46,-45,-45,-44,-42,-41,-39,-38,-36,-36,-36,-35,-35,-35,-35,-35,-35,-35,-35,-37,-38,-41,-41,-42,-44,-45,-46,-47,-47,-47,-47,-47,-47,-47,-47,-47,-47,-46,-45,-44,-43,-43,-41,-41,-40,-40,-38,-36,-35,-35,-33,-33,-31,-31,-31,-31,-31,-31,-31,-31,-31,-32,-32,-32,-33,-33,-33,-35,-36,-37,-37,-38,-38,-40,-40,-40,-42,-42,-42,-42,-42,-42,-42,-42,-41,-39,-38,-36,-35,-33,-31,-30,-30,-28,-28,-28,-30,-31,-31,-33,-34,-36,-38,-42,-42,-44,-44,-46,-46,-46,-46,-46,-46,-45,-45,-45,-45,-43,-42,-42,-42,-42,-42,-42,-40,-40,-40,-40,-40,-40,-40,-39,-39,-39,-39,-39,-39,-39,-39,-39,-39,-41,-41,-43,-45,-47,-47,-48,-49,-49,-50,-52,-52,-53,-55,-55,-55,-55,-55,-53,-51,-50,-48,-46,-45,-43,-42,-42,-42,-41,-40,-39,-39,-39,-39,-39,-39,-39,-41,-43,-43,-45,-46,-47,-51,-51,-52,-52,-54,-54,-56,-56,-56,-56,-56,-56,-56,-56,-56,-56,-55,-55,-54,-54,-52,-52,-52,-50,-50,-49,-49,-46,-46,-45,-45,-45,-45,-45,-45,-45,-45,-45,-45,-45,-46,-46,-48,-48,-48,-49,-49,-51,-51,-52,-54,-54,-54,-54,-54,-54,-54,-54,-53,-52,-50,-48,-47,-45,-43,-42,-42,-40,-40,-38,-38,-38,-39,-39,-39,-41,-43,-45,-45,-47,-48,-49,-50,-50,-52,-54,-54,-54,-56,-56,-56,-56,-56,-56,-56,-56,-56,-55,-55,-55,-55,-55,-55,-54,-52,-51,-51,-49,-47,-47,-45,-45,-45,-45,-45,-45,-45,-45,-46,-46,-46,-46,-46,-46,-47,-49,-49,-51,-53,-53,-53,-53,-53,-54,-54,-54,-56,-56,-57,-57,-57,-57,-55,-54,-52,-51,-49,-48,-48,-48,-48,-48,-48,-48,-50,-52,-54,-54,-56,-58,-58,-60,-62,-62,-62,-62,-62,-62,-62,-62,-62,-62,-62,-62,-62,-62,-62,-62,-62,-61,-61,-60,-60,-58,-57,-56,-55,-54,-54,-52,-52,-50,-50,-48,-48,-48,-48,-48,-48,-48,-48,-48,-48,-49,-49,-51,-51,-51,-51,-53,-53,-53,-54,-54,-56,-57,-57,-57,-58,-58,-58,-58,-58,-58,-58,-57,-55,-54,-52,-51,-51,-51,-49,-49,-49,-49,-50,-50,-52,-52,-53,-54,-56,-56,-56,-58,-58,-58,-58,-58,-58,-58,-57,-57,-57,-57,-57,-57,-57,-55,-53,-53,-53,-52,-50,-50,-49,-49,-47,-47,-46,-46,-44,-43,-43,-42,-39,-39,-38,-38,-36,-36,-34,-34,-34,-34,-32,-32,-32,-32,-32,-32,-34,-34,-34,-34,-34,-34,-34,-34,-34,-34,-34,-34,-34,-34,-34,-33,-31,-30,-28,-27,-27,-27,-27,-27,-27,-27,-27,-27,-30,-31,-33,-33,-36,-38,-40,-41,-43,-45,-45,-47,-47,-47,-47,-47,-47,-47,-47,-47,-47,-46,-44,-44,-42,-40,-38,-38,-36,-36,-36,-36,-36,-35,-35,-33,-33,-33,-33,-33,-33,-33,-34,-34,-34,-34,-34,-34,-34,-34,-34,-34,-34,-34,-34,-34,-34,-34,-34,-34,-36,-37,-38,-40,-42,-43,-43,-43,-41,-41,-41,-41,-41,-41,-41,-41,-41,-41,-39,-39,-40,-40,-40,-40,-42,-42,-42,-42,-41,-41,-41,-41,-39,-39,-39,-38,-37,-37,-35,-35,-33,-32,-32,-32,-32,-32,-32,-32,-32,-33,-33,-33,-33,-33,-33,-33,-33,-33,-33,-35,-35,-36,-36,-38,-40,-40,-41,-43,-44,-47,-49,-50,-50,-52,-52,-52,-52,-52,-52,-52,-52,-52,-50,-49,-47,-46,-46,-46,-46,-46,-46,-46,-47,-47,-47,-47,-49,-51,-51,-53,-53,-53,-53,-53,-53,-53,-53,-53,-53,-53,-53,-52,-52,-52,-52,-51,-50,-48,-48,-48,-47,-47,-47,-45,-44,-42,-42,-40,-40,-40,-40,-40,-40,-41,-41,-42,-44,-46,-46,-47,-49,-51,-51,-53,-55,-56,-57,-57,-57,-57,-57,-57,-57,-57,-57,-56,-55,-55,-53,-50,-48,-48,-46,-45,-46,-46,-47,-49,-51,-53,-55,-56,-58,-61,-64,-66,-66,-66,-66,-66,-66,-66,-66,-66,-65,-65,-65,-65,-65,-65,-65,-65,-65,-65,-63,-63,-61,-61,-60,-58,-57,-56,-55,-53,-51,-48,-46,-46,-46,-46,-46,-46,-46,-46,-46,-46,-46,-46,-46,-47,-47,-51,-53,-53,-53,-56,-57,-57,-58,-59,-59,-59,-59,-59,-59,-59,-58,-56,-54,-53,-52,-50,-48,-47,-46,-44,-44,-44,-44,-44,-44,-44,-45,-46,-49,-50,-52,-53,-54,-55,-57,-59,-61,-62,-64,-66,-66,-68,-68,-68,-68,-69,-69,-69,-69,-68,-68,-68,-68,-67,-67,-66,-65,-65,-63,-62,-60,-60,-58,-57,-55,-54,-53,-52,-52,-52,-52,-52,-52,-52,-52,-52,-52,-52,-52,-52,-52,-52,-53,-53,-53,-53,-55,-55,-57,-58,-58,-60,-60,-60,-60,-60,-60,-60,-60,-60,-60,-60,-60,-60,-58,-56,-53,-51,-50,-47,-45,-43,-41,-40,-40,-39,-37,-37,-37,-37,-37,-38,-39,-41,-43,-45,-49,-51,-53,-53,-55,-56,-57,-57,-57,-59,-59,-59,-59,-59,-59,-59,-59,-59,-59,-59,-58,-57,-56,-55,-53,-53,-52,-52,-50,-48,-47,-46,-43,-42,-42,-40,-40,-40,-40,-40,-40,-40,-40,-41,-41,-43,-43,-45,-46,-49,-51,-53,-53,-53,-55,-57,-57,-57,-57,-57,-57,-57,-57,-57,-57,-56,-54,-52,-50,-48,-46,-44,-43,-41,-40,-39,-39,-39,-39,-41,-42,-43,-47,-48,-50,-52,-54,-56,-57,-59,-61,-63,-64,-65,-64,-64,-64,-64,-64,-64,-64,-64,-64,-62,-62,-60,-60,-60,-60,-60,-59,-59,-59,-58,-57,-56,-54,-53,-51,-49,-49,-47,-47,-47,-47,-47,-47,-47,-47,-47,-47,-47,-48,-48,-50,-50,-53,-53,-54,-56,-57,-57,-57,-59,-59,-61,-61,-61,-61,-61,-61,-61,-60,-58,-56,-55,-54,-52,-50,-49,-48,-47,-46,-46,-46,-44,-44,-44,-44,-44,-44,-44,-45,-47,-49,-51,-54,-55,-57,-57,-59,-59,-60,-60,-60,-61,-61,-61,-61,-61,-61,-61,-61,-61,-61,-59,-58,-56,-56,-55,-55,-53,-53,-53,-51,-49,-48,-47,-44,-41,-40,-40,-36,-36,-36,-34,-34,-34,-34,-34,-34,-34,-34,-34,-35,-37,-37,-39,-41,-42,-43,-45,-47,-48,-50,-50,-52,-53,-55,-56,-58,-58,-58,-58,-58,-58,-58,-57,-56,-56,-54,-52,-50,-50,-49,-47,-46,-46,-46,-46,-46,-46,-46,-46,-46,-47,-49,-51,-53,-54,-55,-57,-57,-59,-60,-61,-61,-61,-63,-63,-63,-63,-63,-63,-63,-63,-63,-63,-63,-62,-62,-61,-60,-59,-59,-57,-57,-55,-55,-54,-52,-48,-46,-44,-42,-42,-42,-42,-42,-42,-42,-42,-42,-42,-42,-42,-42,-43,-43,-44,-46,-46,-49,-50,-50,-51,-51,-54,-55,-56,-58,-60,-61,-63,-65,-66,-66,-68,-68,-68,-68,-68,-68,-68,-68,-68,-68,-67,-65,-64,-62,-60,-59,-57,-56,-56,-55,-54,-54,-53,-51,-51,-51,-49,-49,-49,-49,-49,-49,-49,-49,-50,-50,-52,-53,-54,-56,-56,-58,-60,-61,-62,-63,-64,-65,-67,-67,-67,-68,-68,-68,-68,-68,-68,-68,-68,-67,-67,-67,-65,-65,-63,-61,-60,-58,-57,-57,-57,-56,-54,-54,-52,-51,-51,-51,-51,-51,-51,-51,-51,-51,-51,-51,-51,-51,-51,-51,-51,-51,-51,-51,-51,-52,-54,-54,-54,-56,-58,-58,-58,-60,-60,-60,-61,-61,-63,-63,-63,-63,-63,-63,-62,-61,-59,-57,-56,-50,-48,-46,-45,-43,-41,-41,-41,-42,-42,-42,-44,-44,-45,-47,-49,-51,-51,-53,-53,-55,-55,-55,-55,-55,-55,-55,-55,-55,-55,-55,-53,-52,-50,-50,-50,-50,-48,-48,-47,-47,-45,-44,-44,-40,-40,-37,-35,-34,-34,-34,-34,-34,-34,-34,-35,-35,-35,-37,-39,-39,-41,-42,-43,-44,-46,-48,-49,-49,-51,-51,-52,-53,-54,-54,-54,-56,-56,-56,-56,-56,-56,-56,-56,-56,-56,-56,-55,-53,-53,-50,-50,-48,-47,-45,-43,-43,-42,-42,-42,-43,-44,-46,-48,-49,-51,-51,-53,-54,-54,-56,-58,-58,-59,-61,-61,-61,-61,-61,-61,-61,-61,-61,-61,-61,-61,-61,-61,-61,-61,-60,-60,-60,-60,-58,-58,-58,-58,-58,-57,-57,-55,-55
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Simulation/SimulationCSVData/TestCbAccY.csv b/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Simulation/SimulationCSVData/TestCbAccY.csv
new file mode 100644
index 00000000..807178aa
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Simulation/SimulationCSVData/TestCbAccY.csv
@@ -0,0 +1 @@
+123,123,121,121,121,120,120,120,119,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,120,122,123,123,125,126,127,128,129,131,132,132,132,133,134,133,132,132,130,128,128,127,127,125,125,125,125,123,123,123,123,123,123,121,122,122,122,122,122,119,118,114,111,110,110,110,110,109,108,108,108,107,106,106,106,105,105,105,103,103,103,103,103,103,103,104,104,106,107,107,109,109,111,114,118,120,121,123,125,125,125,125,125,125,125,124,124,122,122,122,120,120,119,119,119,119,119,119,117,117,117,117,118,118,120,122,122,122,122,123,123,125,125,127,128,128,128,127,126,126,123,122,121,121,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,120,120,121,121,123,125,126,127,128,129,129,131,131,131,130,130,130,130,130,128,128,126,124,124,123,122,121,119,119,119,117,117,117,117,117,117,117,117,117,118,118,120,120,121,121,123,123,124,124,124,126,126,126,126,126,126,126,126,126,126,125,124,123,123,121,120,118,116,116,115,114,113,112,111,111,109,109,110,110,111,111,113,114,116,118,120,123,125,126,128,129,131,132,134,135,135,135,135,135,134,134,133,131,129,128,127,125,125,123,123,123,123,123,123,123,124,124,124,126,126,128,128,130,130,131,131,133,134,134,134,136,136,138,138,138,138,138,138,138,138,137,136,134,132,130,128,127,125,124,122,121,119,119,117,117,117,117,116,116,116,116,116,117,117,118,120,121,122,123,124,126,128,129,131,131,131,131,131,131,130,130,128,126,125,124,123,121,119,117,115,115,113,112,112,112,111,110,110,110,110,110,110,110,110,110,108,108,108,108,110,110,111,112,113,114,116,118,118,119,120,120,123,123,123,123,123,123,123,122,122,120,119,118,117,116,114,114,113,111,109,108,108,107,106,105,105,103,103,103,103,103,104,105,107,110,112,115,117,119,120,124,126,127,127,127,127,127,126,126,124,124,122,121,121,119,119,119,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,118,118,118,119,121,122,124,125,126,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,126,126,126,126,126,126,126,126,126,126,126,126,126,127,127,127,128,130,133,135,138,140,142,142,143,143,143,143,143,143,143,142,141,139,139,137,135,133,133,131,129,129,127,127,127,127,127,127,127,127,127,128,128,128,128,130,130,130,131,132,132,132,132,133,133,133,133,133,133,133,132,131,129,128,127,125,124,122,121,120,118,117,115,115,114,112,112,112,112,112,112,112,113,113,113,114,117,118,121,122,123,124,126,127,129,129,130,132,133,133,133,133,133,133,133,133,133,133,132,132,132,131,131,129,127,126,125,124,124,124,122,122,120,120,120,121,123,123,124,124,124,126,128,128,129,131,133,134,134,136,136,136,136,136,136,136,136,136,136,136,135,134,133,130,129,128,126,124,124,123,122,121,121,119,119,118,116,116,116,116,116,116,116,116,117,117,118,120,121,123,125,126,128,128,128,128,128,127,127,127,125,125,123,121,119,119,117,117,115,115,115,115,115,115,113,113,114,114,114,114,114,115,116,116,116,117,117,119,120,121,122,123,125,127,127,127,127,127,127,127,127,127,127,127,127,127,126,126,124,124,122,122,121,119,119,119,117,117,115,115,115,115,115,115,115,115,115,116,117,119,121,122,124,125,127,129,129,129,129,129,129,129,128,128,126,126,123,121,120,120,116,116,114,113,112,112,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,112,113,115,116,118,119,119,121,121,121,121,123,124,125,124,124,124,124,124,124,124,124,122,122,122,122,122,120,120,119,117,115,114,113,111,110,109,107,105,105,105,105,105,105,106,106,107,109,111,115,116,118,120,121,123,123,124,124,124,124,124,124,124,124,124,124,124,124,124,122,122,120,120,120,120,120,120,119,118,118,118,118,118,118,118,118,118,118,118,119,119,120,121,121,121,122,124,125,127,128,128,130,130,130,130,130,132,131,131,131,131,131,131,131,131,129,129,128,128,126,126,124,124,123,122,121,121,120,120,120,120,121,121,121,121,122,122,124,124,125,127,127,128,128,130,131,133,133,133,133,132,132,132,131,130,129,127,125,124,123,122,121,121,121,121,121,121,121,121,121,121,121,120,119,119,119,119,119,119,119,119,120,122,122,123,124,125,126,128,132,132,133,136,137,139,140,141,141,141,141,140,140,140,139,139,139,138,137,136,133,133,132,131,130,128,128,127,125,125,123,121,121,121,121,121,121,121,121,121,121,122,123,124,126,127,129,129,130,130,130,130,130,129,128,124,124,122,122,122,119,118,116,114,112,112,112,110,110,110,110,110,110,110,110,110,110,110,110,111,111,111,111,111,112,113,113,113,114,116,118,119,121,122,122,124,124,124,124,124,124,124,124,124,124,124,123,123,123,123,123,123,121,121,121,121,121,119,119,119,119,119,119,119,119,119,119,120,120,121,121,123,124,126,127,128,129,129,130,130,130,130,130,130,130,130,129,128,128,128,126,124,123,122,120,118,118,118,116,116,116,116,116,116,116,116,116,116,116,116,116,116,117,117,118,119,120,122,122,123,125,127,127,127,128,128,130,130,130,130,130,130,130,130,130,130,129,128,126,125,123,122,121,119,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,118,118,120,123,124,125,126,128,128,128,128,128,128,128,128,127,127,125,125,125,125,125,125,123,123,123,122,122,122,122,120,120,118,118,118,118,116,116,116,116,116,117,117,117,117,117,117,117,117,117,118,119,120,121,122,122,123,125,126,126,128,128,130,131,132,132,132,132,132,132,132,132,131,131,131,130,129,127,127,127,126,125,124,123,121,120,118,116,116,116,116,116,116,116,116,116,116,116,116,114,115,117,118,120,121,123,124,124,126,128,128,128,128,128,128,128,128,127,126,125,125,125,123,123,123,123,121,121,121,121,121,120,118,118,118,116,116,116,116,116,116,117,117,117,118,118,118,118,118,120,120,121,122,123,123,124,126,127,128,129,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,130,130,128,128,128,128,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,129,130,132,132,133,135,137,138,138,138,140,140,140,140,140,140,140,140,139,139,137,137,135,133,131,130,130,130,130,130,128,128,127,126,126,126,126,126,126,126,126,126,127,127,129,129,129,129,129,129,130,134,134,136,136,138,138,138,138,138,138,138,138,138,138,138,136,134,134,134,132,132,130,130,130,130,130,129,128,127,126,126,126,125,124,124,124,124,123,123,123,123,123,123,123,124,124,125,126,126,128,130,131,132,133,134,136,137,138,138,138,138,138,138,138,138,138,137,137,132,130,129,128,127,125,125,124,123,121,119,119,119,119,119,119,117,117,117,117,117,117,117,118,118,120,120,121,123,125,126,126,128,128,128,129,130,132,132,132,132,132,132,132,132,131,129,129,129,127,126,125,124,122,122,121,120,119,119,119,119,119,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,120,120,121,123,124,124,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,125,125,125,123,123,123,122,122,120,120,118,118,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,117,117,119,120,122,124,125,125,126,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,126,126,126,126,124,124,123,123,123,123,123,123,123,123,125,127,129,130,132,134,135,135,136,137,137,137,137,137,137,137,137,137,136,134,132,129,128,126,126,122,121,119,118,118,118,118,116,116,116,116,116,116,116,116,116,116,116,117,118,119,120,120,122,124,125,125,125,125,125,125,125,125,125,125,125,126,127,127,127,127,127,127,127,127,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,127,127,128,128,129,130,133,135,136,138,140,142,143,144,144,144,144,144,143,142,142,139,138,134,133,130,128,126,126,124,124,122,122,122,122,121,121,121,121,121,121,121,121,121,121,121,123,123,124,125,125,126,126,128,129,129,131,131,131,131,131,131,131,131,131,131,131,131,130,130,130,129,128,128,128,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,127,127,129,129,130,132,133,135,137,138,138,138,138,138,137,137,137,135,133,133,133,132,132,132,131,130,129,127,125,123,123,121,121,120,120,120,120,120,120,120,120,120,120,120,120,120,121,121,121,122,122,122,123,124,124,124,126,126,127,127,129,131,131,132,132,134,136,136,136,136,136,135,133,133,133,133,131,131,129,129,127,127,124,123,123,123,123,122,122,121,120,119,117,117,116,116,116,116,116,116,116,116,116,116,118,118,119,119,121,122,124,125,127,127,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,128,126,126,125,124,122,122,122,121,121,121,119,118,117,117,116,116,116,114,114,114,114,114,114,114,114,114,114,115,115,115,116,116,118,118,118,119,119,121,123,124,124,126,127,128,128,128,128,128,128,128,128,128,128,128,128,127,127,127,126,126,125,124,123,121,120,118,117,115,113,112,112,112,112,112,112,112,113,113,114,115,116,118,118,119,120,121,122,122,124,124,124,124,124,124,124,124,123,123,123,121,121,119,117,115,115,115,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,116,117,120,121,122,124,126,126,126,127,128,128,128,128,128,128,128,128,128,126,126,124,124,124,124,124,124,124,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,124,124,126,126,127,129,129,129,129,129,129,129,129,129,129,128,128,126,124,125,125,124,122,122,122,121,121,119,118,117,117,115,115,115,114,114,114,114,114,114,114,114,114,114,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,114,114,116,118,118,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,118,118,118,116,116,115,115,115,114,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,114,115,119,121,122,122,124,125,125,125,127,129,129,131,131,131,131,131,131,131,131,131,131,131,131,131,130,128,127,126,125,125,123,121,121,119,119,119,117,117,115,115,115,114,114,114,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,114,115,116,117,117,119,119,119,119,120,121,121,121,120,120,120,120,120,120,120,120,120,120,118,118,118,116,115,115,113,113,111,111,111,111,109,108,108,107,105,105,105,105,105,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,105,106,107,108,109,111,112,112,114,114,116,118,120,122,122,122,123,124,124,124,124,124,123,123,123,123,123,123,121,119,119,117,117,115,115,113,113,113,113,113,113,113,113,113,113,113,113,113,113,114,114,114,114,114,114,114,114,114,114,114,114,115,115,117,118,120,122,123,123,125,125,126,126,126,126,126,126,126,126,126,126,126,126,126,126,125,123,123,123,123,121,121,121,121,120,120,120,119,118,116,116,115,115,113,113,113,113,113,113,114,114,114,114,114,115,117,117,121,121,121,121,122,123,124,125,125,125,125,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,126,126,126,125,124,124,122,122,120,120,117,117,117,115,113,113,111,111,111,111,111,111,111,111,111,111,111,112,112,112,114,116,118,118,119,119,121,121,121,121,121,122,123,124,125,127,128,128,128,128,129,130,130,130,130,130,130,130,129,128,127,127,127,124,123,122,122,120,120,120,120,120,120,120,119,119,117,117,116,116,116,116,114,114,114,114,114,114,114,114,114,114,115,115,116,116,118,120,121,123,123,125,126,126,128,128,129,129,130,131,132,133,133,133,133,133,133,133,132,132,132,130,130,128,128,128,128,128,127,127,127,127,127,125,125,125,125,124,124,123,123,121,121,121,119,119,119,118,118,118,118,118,118,118,118,118,118,120,121,121,123,123,125,125,125,125,124,125,125,125,125,125,125,125,125,124,124,124,124,124,124,122,122,120,119,119,119,118,117,117,117,117,117,117,117,117,117,117,115,115,116,116,116,118,118,119,119,121,121,121,122,124,125,125,127,127,127,127,129,129,129,129,129,129,129,129,127,127,126,124,122,120,119,119,117,115,115,115,113,113,113,113,113,113,113,113,113,113,113,113,114,114,114,114,114,114,114,114,114,115,115,115,117,119,119,119,119,120,120,122,122,122,122,122,122,122,124,124,124,124,124,124,124,124,122,122,120,120,120,118,117,117,115,115,113,113,111,111,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,112,112,114,115,116,119,120,122,122,124,125,127,128,130,132,134,134,134,135,135,135,135,135,135,135,135,135,135,135,135,134,133,131,131,129,129,127,127,127,125,125,125,125,125,125,125,124,124,124,124,124,124,124,124,124,124,124,124,124,124,125,126,126,126,126,126,128,129,131,132,134,135,135,137,137,137,137,139,139,139,139,139,139,139,139,138,138,138,138,138,138,138,136,136,136,136,134,134,133,132,131,131,131,129,129,129,129,129,129,129,129,129,129,129,129,129,131,132,133,134,135,137,138,139,140,141,143,143,143,143,143,143,143,143,143,143,142,143,143,143,142,140,139,138,135,133,133,131,131,129,129,128,126,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,125,125,127,127,128,128,128,130,132
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Simulation/SimulationCSVData/TestCbAccZ.csv b/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Simulation/SimulationCSVData/TestCbAccZ.csv
new file mode 100644
index 00000000..b9860bdd
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Simulation/SimulationCSVData/TestCbAccZ.csv
@@ -0,0 +1 @@
+191,191,191,190,190,190,190,190,190,190,190,189,189,189,189,189,189,189,189,189,188,188,188,188,188,188,189,189,189,189,189,191,191,193,193,194,195,197,198,199,201,203,203,204,204,205,207,208,208,208,210,210,210,210,209,209,208,208,208,206,204,204,202,201,200,199,199,199,198,197,197,197,197,197,197,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,189,189,189,189,189,189,189,188,188,187,186,186,186,185,184,185,184,184,184,184,185,185,185,185,187,187,187,189,190,190,192,193,195,197,198,201,202,203,204,204,205,206,206,206,205,205,204,204,202,202,200,199,199,199,197,195,195,195,195,195,195,195,195,195,193,193,193,193,194,194,194,194,194,194,194,196,196,196,197,197,198,199,199,199,198,196,195,194,192,192,190,190,190,188,188,186,184,183,181,180,178,177,175,173,173,173,174,174,174,174,174,174,174,174,176,177,180,182,183,185,189,190,192,193,194,197,198,199,201,201,203,204,205,208,208,208,208,208,208,207,207,205,204,204,202,202,200,200,200,198,198,198,198,198,198,198,196,196,194,194,194,194,194,194,194,194,194,194,194,194,194,196,196,196,196,196,195,193,193,193,191,191,189,189,189,189,187,186,186,186,185,182,182,182,180,180,180,180,180,180,180,180,178,178,178,178,178,179,179,181,183,184,187,190,191,193,195,197,198,200,203,206,207,208,210,211,211,213,214,214,214,216,216,216,215,215,214,212,208,205,202,198,196,195,192,191,189,189,187,185,185,183,183,183,183,183,183,183,183,183,183,183,183,184,184,184,185,185,185,187,187,187,187,187,187,187,187,187,184,184,184,181,180,178,176,176,176,176,174,174,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,174,177,179,183,185,186,189,192,193,195,196,197,198,199,201,201,201,201,201,201,201,200,200,199,198,196,195,193,192,191,190,190,188,186,184,184,184,184,183,182,182,183,183,183,183,183,183,185,185,188,188,190,191,193,194,196,197,199,199,201,201,201,201,201,201,201,201,200,198,195,194,194,191,188,186,184,184,182,182,181,181,181,181,181,181,181,181,183,184,185,186,188,190,191,191,193,195,196,198,200,202,203,205,207,207,208,208,208,208,206,204,204,202,200,199,197,193,193,193,191,191,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,187,187,188,188,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,188,187,185,185,183,183,182,180,178,178,177,177,176,176,176,176,176,176,176,176,176,177,177,177,177,178,180,182,183,183,185,186,188,189,191,191,191,195,195,195,195,195,195,195,195,195,195,195,195,194,194,193,192,192,192,192,192,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,193,193,194,196,197,198,198,198,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,197,197,195,193,192,190,190,190,190,188,188,188,188,188,188,188,188,188,188,188,188,189,189,191,191,191,193,194,195,196,196,197,197,199,200,201,202,202,204,205,207,207,209,209,209,209,209,209,209,208,206,204,203,200,200,199,198,194,193,191,189,189,187,186,184,184,182,182,182,182,181,181,181,179,179,179,179,179,179,179,179,179,180,181,181,182,182,184,186,187,188,189,191,194,194,194,194,194,194,194,194,194,194,193,193,192,191,189,186,185,184,182,182,180,180,179,179,177,175,175,174,174,174,174,174,174,174,174,174,174,176,177,178,179,180,181,183,184,186,187,187,189,191,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,190,190,189,187,187,187,186,185,185,183,183,183,183,183,183,183,184,186,186,188,188,189,189,189,191,191,192,192,194,195,197,199,201,201,203,203,205,205,206,206,206,206,206,206,206,206,206,204,202,201,198,198,195,192,191,189,187,187,187,187,187,187,187,187,188,188,189,189,191,192,193,194,196,197,199,200,200,200,200,200,200,200,200,199,198,196,194,194,192,190,189,188,187,187,187,186,186,181,181,180,179,178,178,176,176,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,175,176,178,180,183,184,186,187,189,191,192,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,193,192,191,191,191,189,189,189,189,189,189,189,189,189,189,189,189,189,189,190,192,193,193,195,196,198,199,200,201,203,204,206,206,207,209,209,209,209,209,209,209,209,209,209,208,206,205,203,202,200,200,198,198,197,195,195,194,193,191,191,191,190,189,189,189,189,189,189,189,189,189,189,189,189,189,190,190,190,191,191,191,193,193,195,196,197,198,201,201,202,203,203,204,204,204,206,206,206,206,206,206,206,206,206,206,206,205,205,204,202,200,200,198,198,197,197,195,195,195,195,195,195,195,195,195,195,196,197,198,198,199,201,202,204,206,207,208,209,209,209,209,209,209,209,208,208,205,204,203,200,199,198,195,194,193,193,191,190,190,188,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,187,188,189,189,190,190,190,191,192,194,195,196,197,199,199,199,199,200,201,201,201,201,201,201,200,200,200,198,198,196,194,194,193,193,192,191,191,191,191,191,191,191,189,189,190,190,190,190,192,193,193,197,199,201,203,203,206,208,209,211,211,211,211,210,210,210,208,207,203,201,201,199,196,192,191,189,188,186,186,186,186,186,185,185,185,185,185,185,185,185,185,185,185,185,185,185,187,187,188,188,188,189,190,191,193,194,196,198,199,200,201,201,201,201,201,201,201,201,201,201,201,199,197,195,194,192,187,187,184,182,181,180,179,179,177,177,177,177,177,177,177,177,177,177,178,178,179,181,181,182,185,186,188,190,191,193,196,197,198,200,200,201,201,201,200,200,200,200,199,199,199,197,197,197,197,197,195,194,194,193,192,190,190,188,188,187,187,185,185,185,183,182,182,182,182,180,180,178,178,178,178,178,178,177,177,177,177,177,177,177,177,177,177,178,179,179,181,181,181,183,183,184,184,184,186,187,187,189,191,193,196,196,198,198,199,200,200,200,200,200,200,200,200,199,199,199,199,199,199,197,197,197,196,195,195,194,194,194,192,192,190,190,190,190,190,190,190,190,191,191,191,193,193,194,196,198,199,199,201,202,202,204,205,205,205,207,207,207,207,207,207,207,207,207,206,204,204,201,199,197,195,194,193,192,192,190,190,188,188,186,184,184,184,183,183,183,181,181,181,181,181,181,181,181,181,183,185,185,185,186,186,188,190,190,191,192,192,192,192,192,192,192,192,192,192,192,192,192,191,191,191,191,189,189,189,187,187,187,186,186,186,186,186,186,186,186,184,184,184,184,184,186,188,188,190,192,194,196,198,200,203,204,206,208,214,216,217,219,220,222,222,224,224,224,224,224,224,224,223,223,221,221,216,216,214,212,211,209,205,202,202,201,201,199,197,197,195,195,193,193,192,192,192,191,190,190,190,190,190,190,190,190,190,190,190,190,190,190,192,192,194,195,196,198,198,200,200,202,202,202,202,202,202,202,201,201,201,201,199,199,199,197,197,197,194,193,191,191,190,188,188,186,186,184,184,184,184,185,186,186,188,190,191,193,194,195,198,199,201,203,204,206,206,208,208,208,208,208,208,208,207,207,205,205,203,202,200,198,197,194,194,191,189,187,187,185,183,183,181,181,179,179,179,179,179,179,177,178,178,178,180,182,183,184,185,185,187,188,188,188,190,190,190,190,190,190,190,190,190,190,190,190,190,189,189,188,187,187,186,186,184,182,182,180,179,178,177,177,177,175,175,175,175,175,176,176,176,177,177,179,181,182,184,186,187,189,191,192,194,195,197,198,198,198,198,198,198,198,198,198,198,197,196,196,191,191,191,188,187,186,184,182,180,180,179,178,177,176,175,175,175,175,173,173,173,173,173,173,173,173,173,174,174,177,178,179,181,181,182,183,184,185,187,188,190,191,192,192,192,192,192,192,192,192,192,192,192,192,192,191,189,189,187,185,184,183,183,181,181,181,181,181,182,182,182,182,182,182,184,186,187,189,189,191,192,192,192,194,196,196,196,196,196,196,195,195,195,195,189,189,187,187,185,183,183,182,180,178,178,177,175,173,172,168,166,164,162,161,161,159,158,156,156,156,156,156,156,156,156,156,156,156,156,156,157,157,158,158,160,160,162,163,164,165,165,166,168,169,171,171,173,175,176,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,176,175,175,175,173,173,173,173,173,173,173,173,173,174,175,176,178,181,182,184,185,188,190,191,191,193,194,195,195,195,196,197,197,197,197,197,197,197,197,196,196,194,194,192,190,190,188,186,185,185,185,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,184,185,185,186,186,188,189,190,190,191,191,193,194,195,196,197,198,198,200,200,200,200,201,201,201,201,201,201,199,197,197,197,197,195,193,193,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,193,193,195,197,198,200,200,202,203,205,206,208,209,210,211,212,214,214,214,214,214,214,214,213,213,211,209,208,207,205,204,202,202,199,198,197,195,194,192,192,191,189,188,188,186,185,185,183,181,181,179,179,178,177,177,177,177,177,177,177,177,178,178,178,178,178,179,179,181,181,182,184,185,187,188,188,188,188,188,188,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,190,190,190,190,190,188,188,188,188,188,187,187,187,187,187,189,191,192,194,196,197,199,200,202,204,205,207,208,210,210,210,210,210,209,207,205,203,203,201,198,195,194,192,192,190,189,188,187,186,184,184,184,182,182,182,180,180,180,180,180,180,180,181,181,181,181,183,183,183,183,183,183,183,184,185,186,186,187,189,189,189,190,191,191,191,191,191,191,191,191,191,191,190,190,189,188,185,182,182,182,182,182,182,180,180,180,180,180,180,180,180,181,181,181,181,183,183,183,184,187,187,190,193,194,196,198,199,200,202,203,203,203,203,203,203,203,203,203,203,199,199,197,197,196,194,192,191,191,189,187,185,184,182,181,181,181,181,181,179,177,177,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,176,176,177,178,179,179,180,180,182,183,184,185,185,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,184,184,182,182,182,180,179,179,177,177,177,176,176,176,176,176,176,176,176,178,182,184,185,187,189,190,194,195,196,197,199,200,202,202,202,202,202,201,201,200,200,198,196,195,194,193,193,191,191,189,189,187,187,187,187,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,188,188,188,190,191,193,193,195,195,196,196,198,200,200,202,203,204,205,206,207,208,209,209,209,209,209,209,209,209,209,209,209,209,209,208,208,207,207,207,205,203,203,203,201,200,196,196,194,194,193,193,193,193,193,193,191,191,191,191,191,191,193,194,195,195,196,198,200,200,201,202,204,204,204,204,204,204,204,203,203,203,202,201,200,200,200,198,198,197,195,195,194,193,192,191,190,189,189,187,187,187,185,185,184,184,184,182,182,182,182,182,182,182,182,182,183,183,183,184,184,186,188,189,191,193,193,195,196,197,199,199,201,201,202,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,203,203,202,202,200,200,199,197,195,194,192,190,189,188,188,188,188,188,188,189,190,192,194,195,195,197,197,198,200,203,203,205,206,208,210,211,211,211,211,211,211,211,210,207,206,203,199,197,195,192,190,188,188,187,186,183,183,183,180,178,178,176,175,175,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,176,176,176,177,178,178,179,179,181,182,183,184,184,185,185,187,189,189,190,192,192,194,194,194,194,194,194,194,194,194,194,193,192,192,192,192,192,192,190,190,190,190,190,188,188,188,187,187,187,187,187,187,187,187,188,188,191,193,195,199,200,202,203,203,203,203,203,201,201,199,198,195,192,191,191,189,187,187,185,185,184,183,182,181,181,181,178,177,177,177,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,177,178,179,179,181,183,184,184,185,186,187,188,188,190,190,190,190,190,190,189,189,189,189,189,189,189,189,189,189,189,187,187,186,184,184,182,182,181,179,179,179,179,177,177,177,177,177,177,177,177,177,178,180,182,183,186,189,191,192,196,196,198,199,199,199,199,199,199,199,199,198,196,194,192,190,188,186,185,185,183,182,180,180,179,175,174,172,172,170,169,169,169,167,167,167,167,167,167,167,167,167,165,165,165,165,165,165,165,165,165,165,166,166,166,167,169,170,172,174,175,176,178,180,180,180,180,180,180,179,179,179,179,179,177,178,178,178,178,177,176,176,176,174,174,172,172,170,169,168,167,167,166,164,164,164,164,165,165,165,166,166,166,166,166,166,168,169,170,171,173,175,176,178,180,183,185,186,188,189,191,192,194,194,194,194,194,193,192,192,190,189,187,185,183,181,179,176,176,175,174,173,171,169,168,168,166,166,165,165,165,165,165,165,165,165,166,166,166,167,167,168,169,169,169,170,170,171,172,172,173,173,173,175,176,179,180,181,181,184,185,185,186,187,187,187,187,187,187,187,187,187,187,187,187,186,186,184,183,183,181,181,179,178,176,172,172,170,170,170,170,170,170,170,172
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Simulation/SimulationCSVData/TestElAccX.csv b/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Simulation/SimulationCSVData/TestElAccX.csv
new file mode 100644
index 00000000..8d289441
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Simulation/SimulationCSVData/TestElAccX.csv
@@ -0,0 +1 @@
+62,62,64,64,65,65,67,66,64,63,63,61,59,59,59,62,62,64,66,67,69,69,68,66,66,65,65,63,62,60,60,60,60,60,63,63,64,66,67,69,71,72,74,75,75,75,75,75,73,72,70,68,67,67,65,64,64,62,62,62,62,63,64,67,68,69,71,72,74,74,74,74,73,71,70,68,67,65,64,62,60,59,59,59,59,59,60,61,63,64,66,67,67,67,67,67,67,67,67,63,63,63,62,60,58,57,57,57,57,57,59,61,63,65,68,69,70,71,72,72,72,72,70,68,67,65,63,62,60,59,59,59,59,59,60,61,63,64,66,67,69,70,70,70,70,70,68,66,64,62,61,60,58,58,57,57,57,57,59,61,62,64,65,67,69,69,69,69,69,68,66,65,63,62,60,58,58,58,58,59,61,62,64,66,66,66,66,66,65,65,63,62,61,60,60,59,59,59,59,59,60,60,61,63,65,66,68,68,68,67,67,65,64,63,62,61,61,59,59,58,57,57,58,58,60,61,63,64,66,67,67,67,69,69,69,69,69,68,68,66,65,64,63,62,62,62,62,60,60,60,61,62,63,65,67,68,70,71,71,71,71,70,68,67,65,62,61,60,59,58,58,56,56,56,56,56,56,56,57,58,59,60,61,61,63,63,63,63,63,63,62,61,60,59,57,55,54,54,54,52,52,53,55,56,58,59,60,61,62,64,64,64,64,64,64,64,64,63,63,62,60,59,59,59,59,59,59,60,60,62,64,65,66,67,67,69,69,69,69,68,68,67,66,65,63,61,60,58,57,57,57,57,57,57,57,57,57,59,61,61,62,63,64,63,62,61,60,58,56,53,53,52,52,50,50,50,50,50,51,51,53,55,57,58,59,61,62,63,64,63,63,63,62,61,60,58,56,53,53,52,51,50,50,48,48,48,49,51,52,54,55,59,61,62,64,64,64,64,64,63,61,61,57,54,53,51,50,49,48,48,48,48,48,49,51,53,56,57,61,62,64,64,64,64,63,61,59,56,54,53,51,50,50,48,48,48,48,49,50,52,53,54,55,57,58,58,58,58,58,58,56,54,53,51,50,49,48,48,48,48,48,48,49,51,52,54,55,57,57,58,59,60,60,60,60,59,58,57,56,54,53,51,50,50,50,50,50,50,51,53,54,59,61,62,63,64,65,65,65,65,65,63,63,60,58,57,57,56,55,55,55,55,56,59,61,62,65,66,68,70,71,73,73,73,73,72,72,72,69,65,64,61,60,59,57,55,55,55,56,58,59,61,63,64,66,68,69,70,71,72,72,72,71,71,69,69,66,64,63,61,61,60,58,58,58,59,59,61,63,64,66,67,68,69,69,68,68,66,64,64,63,61,61,60,60,60,60,60,60,61,63,64,66,68,69,71,72,72,72,72,72,68,66,63,61,59,57,56,54,54,54,55,57,60,61,64,67,68,69,70,70,69,69,68,67,66,66,65,65,65,65,65,65,65,67,69,70,71,72,72,72,71,69,69,67,66,64,64,64,64,65,66,69,71,72,73,74,74,74,74,73,71,70,67,67,65,64,64,62,62,62,63,65,65,66,68,69,71,72,72,72,72,72,72,71,70,69,67,65,63,62,61,60,60,61,61,63,65,67,68,70,71,73,74,74,74,74,74,72,71,68,66,65,64,64,63,62,62,62,62,63,65,66,68,70,71,71,72,72,72,72,72,71,70,69,67,64,62,61,61,59,59,59,61,62,65,68,71,73,74,76,77,77,79,79,79,79,78,74,73,71,67,65,63,61,59,57,57,57,57,57,57,58,60,63,65,68,71,73,74,74,75,76,76,76,75,72,70,66,62,59,57,54,52,51,51,52,54,56,60,61,63,67,69,73,77,78,81,82,84,86,86,86,85,84,81,79,77,75,74,72,70,69,67,66,66,66,66,67,68,70,73,77,79,80,83,85,87,88,88,88,88,88,85,81,78,76,71,69,65,64,62,61,59,57,57,56,56,56,56,56,58,60,62,65,69,71,76,80,82,84,85,86,87,88,88,88,87,86,84,81,78,72,70,66,61,58,56,54,53,51,51,51,51,51,53,56,60,62,69,74,81,86,89,93,95,96,98,99,101,101,102,104,104,104,103,102,98,98,94,91,87,83,79,77,73,70,69,67,66,64,64,63,63,61,61,62,62,64,66,70,74,81,86,90,93,97,100,102,102,102,103,103,103,103,100,97,97,91,88,85,81,78,75,72,70,68,65,64,62,62,60,58,58,58,58,59,61,63,66,66,68,71,76,79,81,85,86,88,89,88,87,87,84,80,75,71,69,65,64,61,60,59,57,57,57,58,58,60,62,62,66,68,70,72,73,74,76,77,79,78,76,74,71,66,62,58,55,52,48,46,45,43,42,42,40,40,40,41,43,44,45,49,52,55,57,59,60,62,62,62,61,59,57,55,50,48,47,44,43,41,40,40,41,44,46,48,53,54,60,63,69,70,72,73,74,75,75,75,75,74,72,70,67,64,62,58,57,53,49,48,46,44,43,43,43,43,43,43,44,44,46,48,51,54,57,61,63,66,68,70,71,72,73,73,72,70,67,63,60,54,53,49,45,43,38,36,34,33,31,31,31,31,32,34,36,39,43,47,51,55,57,60,61,63,63,63,63,63,62,61,59,57,53,50,48,43,41,40,39,37,37,37,37,37,38,39,40,43,45,48,51,54,57,60,63,65,68,70,71,71,71,70,68,64,61,57,50,44,36,30,28,23,21,20,18,18,18,18,18,18,19,19,20,22,25,29,31,33,35,37,39,40,41,43,44,45,46,49,53,58,67,74,84,89,93,97,98,100,100,100,100,97,97,93,90,86,83,78,73,69,65,64,61,58,57,55,54,53,52,51,51,51,51,52,52,54,56,59,63,65,69,73,76,83,87,91,93,95,96,97,98,97,95,94,91,88,83,79,75,72,67,64,61,60,60,60,61,62,64,67,72,74,79,82,86,87,89,90,92,92,92,92,89,87,84,81,77,71,70,63,61,59,58,58,58,58,59,59,61,62,65,68,72,74,77,79,81,82,84,85,85,87,87,86,84,81,77,73,70,69,65,62,60,57,56,56,56,56,56,56,57,58,61,64,67,69,72,77,80,85,88,90,93,94,96,98,98,97,95,93,89,85,81,77,75,71,67,66,63,62,60,60,60,60,60,60,61,64,66,69,70,74,75,79,81,82,84,85,85,85,85,85,84,82,80,78,74,70,64,62,58,54,53,52,51,51,50,51,53,58,61,66,70,73,74,76,80,81,82,82,82,82,82,80,77,74,70,67,65,61,59,56,54,54,54,54,54,54,56,58,61,63,65,67,70,71,73,75,75,75,74,72,70,66,65,63,62,60,58,55,53,53,53,53,54,54,56,59,60,64,67,70,73,76,79,81,81,81,81,81,80,77,72,69,63,60,56,53,51,50,50,50,52,57,61,64,70,74,78,80,82,84,85,85,85,83,81,79,77,76,75,73,70,70,67,65,66,67,69,73,76,79,83,86,88,89,91,91,90,88,85,82,78,75,72,69,68,66,65,65,65,65,66,67,70,73,74,76,77,79,83,83,83,83,82,79,77,75,68,66,62,53,51,46,44,42,40,39,38,38,38,39,41,43,49,52,55,58,61,64,65,65,65,65,64,62,60,59,57,52,50,47,45,44,42,42,42,42,42,42,45,46,51,55,58,60,62,65,66,68,70,70,70,70,70,70,69,67,65,63,61,59,57,55,54,52,52,52,53,53,55,59,63,64,68,71,72,73,73,73,73,72,71,67,63,60,56,53,48,45,42,40,38,37,37,37,37,37,42,45,48,52,56,61,63,67,70,71,73,73,73,73,73,72,68,66,63,60,58,55,54,53,52,51,51,51,51,51,52,53,54,56,61,63,67,70,72,75,77,79,80,81,81,81,81,81,80,77,73,62,57,53,51,49,47,47,45,45,45,45,45,45,45,53,55,58,61,62,64,65,67,67,67,67,67,66,61,59,55,49,46,44,40,38,37,37,35,35,35,35,38,39,42,45,49,52,55,59,60,65,68,69,71,73,73,74,75,75,75,75,72,70,68,64,60,57,53,49,47,45,44,42,41,41,38,38,38,38,39,43,47,50,54,57,64,67,69,71,72,72,72,73,74,74,74,73,71,68,62,59,55,50,44,40,38,36,35,35,35,37,40,45,49,56,63,67,72,73,73,73,73,73,73,71,69,67,63,62,60,59,58,58,59,61,65,68,70,75,79,82,83,84,85,82,79,77,72,70,65,62,59,57,55,55,55,56,59,62,63,66,69,70,72,73,73,75,76,76,76,76,76,76,76,76,72,70,68,64,63,61,61,62,64,64,68,69,71,73,74,75,76,76,75,73,71,67,65,61,60,56,55,53,53,54,56,59,63,66,69,71,73,76,77,78,77,75,74,70,68,64,61,60,59,58,58,58,60,62,65,67,69,72,75,78,80,82,82,82,81,79,79,75,73,71,68,66,65,64,63,63,64,65,67,70,72,75,77,78,80,81,81,80,79,75,74,72,70,69,67,65,64,63,63,63,64,65,67,70,71,73,74,75,76,76,76,76,76,76,75,73,69,67,64,62,61,59,59,59,59,60,62,64,66,70,71,73,74,75,76,75,75,73,70,68,66,63,61,59,57,56,54,54,56,57,59,61,63,66,70,72,72,73,72,72,71,67,64,62,58,56,54,53,51,51,51,52,54,56,58,61,62,66,68,69,69,69,69,68,67,65,62,60,58,56,55,55,55,55,55,55,55,56,57,59,60,62,63,65,65,67,67,67,66,62,60,58,54,52,49,47,46,46,46,47,47,50,52,54,56,58,60,62,62,62,61,59,56,53,51,46,44,41,39,37,37,37,37,38,40,44,46,48,51,53,56,59,60,60,60,60,59,57,55,52,49,46,43,41,40,38,38,38,39,41,43,49,52,54,55,58,59,60,62,62,62,60,59,55,53,49,46,44,41,40,37,35,35,36,36,38,40,43,45,50,52,57,59,60,62,62,62,62,62,62,57,55,50,47,44,42,39,38,37,37,37,37,40,40,42,44,47,49,50,51,52,53,55,55,55,55,55,55,55,51,50,47,44,43,41,39,38,36,36,36,36,36,39,40,41,44,47,51,53,56,59,60,61,62,62,62,62,62,61,59,58,55,53,50,46,43,36,34,31,30,28,27,27,27,27,28,30,32,35,37,43,44,48,50,51,53,53,53,53,50,48,45,42,40,37,33,32,29,28,28,27,27,28,31,34,37,41,45,48,52,56,57,59,58,56,54,52,49,47,43,40,35,32,32,33,36,38,43,46,53,57,58,58,58,58,56,52,50,46,43,40,38,37,36,35,35,36,37,40,46,49,51,56,60,62,64,64,64,64,63,62,60,57,55,53,50,46,45,43,43,44,46,48,52,54,55,58,60,64,65,66,66,66,65,63,59,57,55,51,48,45,44,43,43,43,42,42,42,42,43,45,45,47,49,52,54,55,57,57,57,57,57,57,53,52,47,43,39,36,34,33,31,29,29,29,30,33,33,37,40,42,45,48,50,53,54,54,54,54,53,52,50,48,44,42,37,34,33,31,30,28,28,28,28,29,31,34,35,38,40,44,46,47,50,51,51,51,51,49,47,45,41,37,35,32,30,29,28,27,27,27,27,27,30,32,37,40,43,47,51,53,52,52,50,47,44,42,35,31,28,25,24,22,22,22,23,23,23,25,27,31,33,36,39,41,43,47,49,49,50,50,50,52,52,52,52,52,51,48,46,42,38,35,32,31,29,30,31,35,37,39,47,52,59,63,66,67,69,70,70,70,68,68,66,66,66,69,72,76,78,80,83,86,87,89,89,88,86,83,79,70,67,64,63,61,59,58,58,58,59,59,61,63,64,66,69,76,77,79,79,79,78,76,74,73,69,66,63,62,57,56,55,55,55,56,56,63,65,67,70,72,73,75,75,74,74,71,68,65,62,60,55,53,51,49,49,50,52,53,55,58,60,64,68,71,74,76,78,78,78,78,77,75,72,69,63,60,57,54,51,49,48,47,46,46,46,46,47,51,53,56,58,61,64,66,69,71,72,73,73,73,73,73,73,70,66,63,59,57,49,47,45,45,44,44,42,42,42,42,42,42,43,43,45,46,50,52,55,59,60,62,63,64,65,65,67,67,67,67,66,65,64,62,61,57,55,54,50,50,49,47,45,45,44,42,42,42,42,43,43,45,48,53,55,59,63,66,74,75,77,78,78,80,80,80,77,75,73,69,65,62,58,55,53,50,50,48,46,46,46,46,47,49,52,56,59,60,62,63,65,65,62,59,55,53,47,43,39,37,35,34,34,35,37,42,45,48,52,56,60,61,62,63,63,63,62,60,58,56,55,51,48,46,44,42,41,41,41,42,42,43,47,49,51,53,56,57,61,63,63,64,64,64,64,64,63,60,58,55,52,50,47,46,44,43,42,41,41,41,41,41,42,43,44,48,49,51,53,55,59,62,63,64,65,65,66,66,66,66,65,64,61,60,57,54,50,47,45,42,41,39,40,42,43,45,47,49,52,54,56,57,59,59,59,59,59,58,54,53,50,46,45,42,40,38,38,38,38,38,38,39,40,42,44,45,48,50,51,53,54,54,54,54,56,56,56,56,55,53,53,51,50,46,44,43,40,40,38,38,38,38,38,38,38,39,41,43,45,46,50,52,53,54,55,55,56,56,56,55,55,55,55,54,50,48,47,45,43,43,42,40,40,38,38,38,38,38,38,38,38,39,40,42,43,45,46,48,48
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Simulation/SimulationCSVData/TestElAccY.csv b/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Simulation/SimulationCSVData/TestElAccY.csv
new file mode 100644
index 00000000..8b7aff18
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Simulation/SimulationCSVData/TestElAccY.csv
@@ -0,0 +1 @@
+9,9,9,9,9,10,10,12,10,8,8,7,5,5,6,7,9,10,10,12,13,15,16,16,14,13,11,10,9,9,8,7,5,5,4,4,4,4,4,4,6,9,10,13,13,14,16,17,19,20,22,22,22,21,18,17,17,15,15,14,14,12,12,12,12,12,13,14,16,18,19,21,22,22,24,24,25,25,24,23,22,20,19,17,16,14,12,12,11,11,11,11,14,16,19,21,22,23,24,24,24,24,22,21,19,18,16,14,13,11,10,9,9,6,6,6,6,7,9,12,14,14,17,18,19,20,22,22,22,22,20,18,18,16,14,13,11,10,8,8,7,7,7,7,7,7,7,9,10,12,12,15,17,19,20,21,22,24,24,24,25,24,24,23,21,19,18,17,15,14,13,13,13,13,14,15,17,19,20,22,23,23,23,23,23,19,17,16,16,14,14,14,14,15,16,15,14,12,12,12,13,15,16,18,21,23,24,25,27,27,27,27,26,25,24,22,20,20,19,19,17,17,17,17,18,19,21,22,24,26,27,28,29,30,30,30,29,27,26,24,23,21,20,20,18,16,14,14,13,13,13,15,16,17,19,21,21,22,23,24,24,24,24,22,19,18,16,13,12,10,9,9,8,5,5,3,2,2,2,4,5,7,9,10,10,11,12,13,13,13,13,13,15,15,14,13,11,9,9,8,7,5,3,2,1,0,1,1,2,3,5,6,8,9,9,7,7,6,6,4,3,1,-1,-1,-1,-1,-1,0,2,2,4,6,9,12,12,13,15,17,18,20,20,20,20,20,20,20,19,17,16,14,12,11,9,7,7,6,4,4,3,0,-1,-3,-3,-3,-3,-3,-2,-2,0,1,1,3,4,6,7,9,11,11,11,12,13,14,15,16,15,15,13,10,9,7,4,4,0,-5,-5,-6,-9,-13,-15,-15,-18,-21,-26,-27,-27,-27,-27,-27,-22,-21,-19,-17,-14,-10,-9,-7,-5,-5,-4,-2,-1,1,1,1,1,2,2,2,2,2,1,-1,-1,-3,-4,-6,-7,-9,-11,-13,-13,-13,-12,-10,-9,-9,-5,-2,1,4,4,5,7,8,8,10,10,10,11,12,14,14,14,14,14,13,9,7,7,5,3,2,2,1,-1,-1,-3,-4,-6,-7,-9,-12,-12,-12,-12,-12,-11,-8,-4,-4,-2,1,2,2,4,5,6,9,9,10,10,12,12,12,12,12,12,12,11,8,6,6,4,1,-1,-1,-3,-6,-7,-9,-11,-13,-14,-14,-14,-13,-12,-11,-8,-5,-5,-3,1,1,2,3,4,5,5,7,8,9,9,10,12,12,12,12,12,11,11,10,9,8,8,7,6,3,1,1,-1,-1,-1,-1,0,1,3,3,4,6,7,9,11,11,11,12,12,12,12,12,12,12,10,10,10,8,8,7,7,7,7,8,9,9,11,11,12,12,12,12,10,10,8,8,7,5,3,3,3,3,3,4,7,8,10,11,11,11,12,13,14,15,16,16,16,16,16,16,16,15,13,13,12,10,10,7,7,7,6,5,4,4,4,5,6,8,9,11,11,11,12,12,12,12,12,12,10,9,9,7,6,5,5,5,5,6,7,9,10,10,12,13,14,14,14,14,14,13,12,11,10,8,8,7,5,3,2,1,0,0,0,1,4,5,5,6,7,8,10,11,11,13,15,15,15,16,18,18,18,18,17,16,15,14,12,11,9,9,8,8,6,6,5,5,3,3,5,7,9,10,10,11,11,13,13,13,11,11,12,12,11,9,9,8,6,5,5,5,3,3,6,8,12,15,18,18,21,21,23,25,26,26,28,28,28,26,25,24,23,23,21,20,18,17,16,15,13,13,13,14,16,18,21,22,24,25,28,30,32,32,34,34,35,35,35,35,33,32,30,28,27,25,24,22,20,19,17,14,11,11,11,11,11,15,17,19,20,22,23,25,25,27,27,28,28,28,28,25,23,20,20,18,16,15,14,13,12,10,9,9,9,7,7,9,12,12,14,16,17,20,22,24,25,26,27,27,29,29,29,29,28,26,25,22,21,20,18,15,13,11,11,9,9,9,10,11,11,15,17,20,22,23,25,27,28,28,30,30,32,31,29,29,27,26,24,23,23,21,20,17,14,12,12,12,12,12,12,14,16,17,21,23,24,24,24,24,24,24,22,20,20,19,17,15,13,13,11,11,11,14,15,17,19,21,21,22,22,22,22,22,22,22,22,21,20,19,17,17,15,15,15,15,17,18,19,20,21,22,23,24,24,24,24,24,23,23,22,20,19,18,17,16,15,15,12,11,11,11,11,13,14,15,16,17,19,19,21,23,23,23,23,23,23,22,20,19,17,16,14,12,12,12,10,8,7,7,7,8,9,13,13,17,20,21,23,25,26,27,28,30,30,30,30,30,29,28,27,25,23,22,20,20,20,20,21,22,25,27,29,31,31,31,32,32,32,32,32,31,29,26,25,23,22,20,19,17,14,11,7,2,2,0,-2,-2,-2,-2,1,3,4,4,8,10,11,11,13,13,14,15,16,16,18,18,18,17,17,17,17,16,12,12,10,10,11,11,13,15,17,19,20,22,24,25,27,29,29,32,32,34,34,34,34,34,32,30,29,27,26,24,23,22,19,19,17,17,17,18,19,21,23,24,26,27,29,30,31,32,32,33,33,33,33,31,31,30,28,28,26,26,26,27,30,32,34,36,37,37,37,37,37,37,35,33,33,32,32,30,30,30,31,32,34,36,37,40,42,44,44,44,44,43,43,41,39,36,35,33,33,31,29,29,30,30,32,35,36,37,38,38,38,38,38,38,36,36,36,36,37,38,41,42,43,45,45,45,44,44,43,41,39,38,36,35,33,31,29,29,29,30,32,33,37,38,39,40,42,42,43,43,43,45,45,45,45,45,45,43,41,40,40,38,38,37,37,37,37,40,41,42,43,44,45,46,46,46,45,44,42,42,42,42,42,44,45,45,45,45,43,42,40,41,42,44,45,45,45,45,43,45,48,49,50,51,51,51,51,50,50,49,47,46,44,43,43,43,43,45,46,48,50,52,53,55,55,55,55,55,55,54,53,53,51,50,49,48,48,47,47,47,47,49,51,52,54,54,55,55,55,55,55,54,54,51,49,48,46,45,44,44,44,44,44,44,47,48,49,49,48,45,43,42,40,40,40,40,41,43,44,46,47,49,50,51,51,51,51,50,50,49,48,47,47,46,44,43,42,41,40,39,37,35,34,33,31,29,29,29,30,33,35,39,42,44,46,47,47,47,47,45,42,40,38,37,35,34,32,32,32,31,31,31,33,33,33,33,33,32,32,29,27,25,24,23,22,22,22,20,19,18,18,18,19,23,25,28,32,35,39,40,42,42,42,41,40,37,36,34,30,27,26,25,23,22,21,19,17,17,17,17,17,17,18,19,22,22,23,24,24,24,24,21,19,16,15,14,13,12,10,9,7,7,7,7,7,7,8,9,11,13,13,14,16,16,16,15,15,13,12,10,9,7,7,6,4,2,2,2,3,3,4,6,8,9,11,12,12,14,14,14,14,14,14,13,12,11,8,8,6,3,1,0,0,0,0,0,2,3,5,7,9,10,10,12,14,14,16,17,17,17,17,17,17,17,15,13,12,11,10,10,8,5,5,4,4,4,4,4,6,8,11,14,14,17,20,22,24,25,25,27,27,27,27,27,26,25,23,19,18,16,13,11,10,9,8,8,6,5,3,3,3,3,3,3,6,10,10,14,19,21,22,24,25,25,25,23,22,19,15,11,5,2,2,-2,-3,-3,-4,-5,-6,-6,-6,-6,-6,-6,-5,-4,-2,-1,2,3,3,4,5,5,5,5,5,5,5,4,1,-1,-1,-2,-4,-5,-7,-9,-10,-11,-11,-11,-11,-10,-8,-5,-3,0,3,3,4,6,7,7,7,7,7,7,7,5,4,1,-1,-3,-4,-4,-6,-7,-8,-8,-8,-8,-8,-8,-7,-5,-3,-2,0,0,1,1,1,1,1,1,0,-1,-4,-4,-5,-7,-8,-9,-11,-11,-12,-12,-12,-12,-11,-9,-6,-2,-2,1,5,5,7,10,10,12,12,12,12,12,9,9,7,5,0,-2,-2,-5,-8,-9,-10,-11,-11,-12,-12,-12,-12,-11,-10,-7,-7,-4,-2,3,5,5,6,8,10,10,11,11,11,11,10,7,7,4,2,-1,-4,-4,-7,-8,-10,-10,-11,-12,-13,-13,-14,-14,-14,-14,-14,-12,-11,-9,-5,-5,-2,0,0,2,3,3,3,3,3,2,1,1,-1,-1,-3,-7,-8,-9,-10,-11,-11,-13,-13,-15,-15,-15,-15,-14,-12,-9,-9,-8,-4,-1,1,1,3,4,6,6,8,8,8,8,8,5,3,-1,-4,-6,-6,-8,-9,-11,-12,-12,-14,-14,-16,-16,-18,-18,-18,-18,-17,-17,-14,-12,-9,-6,-6,-5,-3,-1,0,2,2,3,3,3,5,5,5,5,4,2,0,-4,-4,-5,-10,-10,-13,-16,-18,-20,-21,-22,-25,-25,-25,-25,-25,-23,-20,-16,-13,-10,-7,-7,-5,-5,-5,-5,-6,-10,-13,-13,-15,-18,-21,-23,-26,-26,-27,-27,-29,-28,-27,-25,-23,-20,-17,-15,-13,-13,-15,-17,-20,-21,-23,-24,-26,-27,-27,-24,-22,-18,-15,-12,-10,-10,-8,-8,-7,-7,-7,-7,-8,-10,-13,-13,-14,-17,-19,-21,-22,-24,-24,-25,-25,-27,-27,-27,-26,-26,-22,-19,-15,-12,-8,-7,-7,-4,-3,-2,-2,0,0,0,0,-1,-1,-5,-7,-8,-11,-15,-15,-16,-18,-20,-21,-21,-23,-24,-26,-28,-30,-30,-30,-29,-28,-25,-23,-20,-17,-14,-10,-10,-9,-9,-9,-8,-7,-7,-7,-6,-6,-6,-6,-6,-6,-8,-11,-11,-14,-15,-17,-18,-22,-25,-27,-29,-29,-29,-29,-29,-28,-25,-22,-19,-14,-11,-8,-8,-6,-4,-3,-3,-1,-1,-1,-1,-1,-1,-1,-3,-6,-8,-11,-14,-17,-17,-18,-22,-23,-25,-27,-28,-28,-32,-32,-34,-34,-34,-34,-33,-30,-26,-23,-19,-17,-14,-12,-9,-9,-9,-7,-6,-5,-4,-4,-4,-4,-4,-5,-5,-8,-11,-14,-14,-15,-17,-18,-19,-19,-19,-16,-14,-11,-9,-9,-4,0,0,3,6,7,9,11,11,12,12,13,14,15,15,15,15,15,15,15,14,14,11,11,8,8,7,6,6,4,4,4,4,4,6,10,11,11,14,16,17,19,19,19,19,19,19,19,19,18,16,15,13,11,10,8,8,8,7,7,5,5,5,5,5,5,6,14,15,15,19,21,23,23,24,24,24,24,24,24,24,23,21,19,17,15,14,12,10,10,9,9,9,9,9,11,11,12,15,16,20,22,23,25,26,28,29,29,29,29,29,28,28,28,25,22,20,18,15,11,10,10,8,8,8,8,10,13,13,14,16,17,19,21,22,22,24,24,24,24,24,24,24,21,19,17,15,12,11,9,9,8,8,8,8,8,8,9,11,14,14,15,19,21,24,26,28,30,30,30,29,27,25,23,20,17,13,10,8,8,6,5,5,5,5,3,3,3,4,7,10,12,12,14,16,18,19,21,22,22,22,22,20,18,17,15,14,12,12,11,11,9,9,7,7,8,8,10,10,10,11,13,13,13,12,12,12,11,9,9,7,5,4,2,1,-1,-1,-1,-1,-1,-1,0,1,1,1,4,5,6,7,9,11,11,11,11,11,11,11,10,10,8,8,7,5,5,6,6,7,9,11,13,13,14,16,16,16,16,16,16,13,11,10,8,6,6,5,3,3,3,3,3,3,4,6,8,10,12,12,14,14,14,14,14,14,13,13,11,9,9,8,7,5,3,2,0,0,-1,-2,-3,-3,-3,-3,-3,-3,-3,-1,0,0,2,3,5,6,6,8,8,8,8,7,6,4,3,1,0,-2,-2,-4,-4,-5,-5,-5,-5,-5,-5,-2,1,1,3,7,10,13,13,17,18,18,20,20,20,20,19,18,15,14,13,9,9,5,3,1,-2,-2,-5,-7,-8,-11,-12,-13,-13,-13,-13,-13,-12,-12,-12,-10,-9,-7,-7,-5,-2,-1,1,1,1,1,1,0,0,-2,-4,-4,-7,-10,-10,-11,-15,-18,-20,-20,-22,-22,-22,-22,-21,-19,-17,-14,-12,-9,-5,-5,-1,3,3,6,8,9,9,9,8,7,4,1,-5,-5,-7,-9,-14,-17,-20,-20,-21,-23,-24,-27,-28,-28,-29,-30,-30,-32,-32,-32,-32,-32,-32,-32,-31,-31,-31,-30,-28,-26,-23,-21,-18,-14,-11,-9,-8,-8,-6,-6,-4,-4,-4,-4,-4,-5,-7,-9,-12,-12,-15,-18,-21,-25,-28,-31,-35,-38,-39,-41,-41,-42,-42,-42,-38,-36,-33,-28,-24,-18,-13,-10,-5,-2,-2,-1,1,1,2,2,4,4,4,4,4,4,3,1,-1,-4,-4,-6,-9,-12,-14,-14,-16,-18,-19,-21,-23,-24,-24,-26,-26,-26,-26,-26,-26,-26,-22,-20,-18,-14,-11,-6,-6,-3,-2,-1,0,0,0,0,0,0,0,-2,-4,-4,-6,-8,-12,-14,-14,-18,-21,-23,-25,-27,-28,-29,-29,-29,-29,-29,-28,-27,-24,-22,-19,-15,-12,-7,-2,-2,2,4,4,6,7,7,8,9,9,8,8,6,3,1,-3,-3,-6,-9,-11,-14,-14,-15,-17,-19,-20,-20,-22,-22,-22,-22,-22,-22,-21,-21,-20,-18,-16,-15,-13,-10,-9,-9,-8,-7,-6,-5,-4,-4,-2,-2,-2,-2,-2,-3,-4,-7,-9,-10,-10,-12,-16,-18,-20,-22,-24,-26,-27,-29,-29,-31,-32,-32,-34,-34,-34,-33,-32,-29,-28,-25,-23,-19,-15,-13,-12,-10,-9,-9,-9,-9,-9,-9,-9,-9,-9,-12,-12,-13,-16,-20,-22,-25,-27,-30,-32,-33,-35,-36,-37,-38,-40,-41,-41,-41,-41,-41,-41,-39,-39,-37,-35,-30,-26,-22,-17,-15,-11,-10,-8,-8,-7,-5,-5,-5,-5,-6,-7,-9,-10,-13,-13,-13,-17,-18,-21,-22,-24,-25,-27,-28,-30,-30,-32,-32,-32,-32,-32,-30,-28,-27,-24,-22,-19,-17,-15,-12,-11,-11,-11,-11,-11,-11,-11,-13,-17,-18,-22,-25,-27,-29,-30,-32,-34,-35,-35,-37,-37,-37,-37,-35,-32,-30,-26,-21,-18,-15,-13,-11,-11,-11,-11,-11,-12,-13,-15,-19,-20,-23,-25,-26,-27,-27,-27,-27,-27,-26,-24,-23,-21,-20,-18,-16,-15,-15,-13,-13,-13,-13,-13,-14,-15,-17,-18,-20,-21,-22,-23,-25,-25,-25,-27,-27,-27,-27,-27,-27,-27,-26,-25,-23,-23,-22,-22,-20,-18,-18,-18,-17,-17,-17,-17,-17,-17,-18,-18,-19,-20,-21,-22,-23,-24,-25,-26,-27,-29,-30,-30,-30,-32,-32,-32,-32,-32,-33,-33,-33,-33
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Simulation/SimulationCSVData/TestElAccZ.csv b/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Simulation/SimulationCSVData/TestElAccZ.csv
new file mode 100644
index 00000000..1227535c
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Simulation/SimulationCSVData/TestElAccZ.csv
@@ -0,0 +1 @@
+224,224,224,222,222,221,221,221,221,225,227,227,229,233,236,238,241,243,244,244,243,242,240,238,237,234,231,229,226,225,222,221,220,220,219,218,218,219,220,222,223,225,225,226,228,230,231,232,233,233,233,233,232,231,229,228,226,224,223,221,220,219,219,218,218,218,219,221,224,230,236,239,244,246,248,249,251,251,251,251,251,250,248,243,240,238,234,229,226,223,221,219,216,215,213,213,213,214,216,219,221,221,224,228,230,234,236,237,238,238,238,238,236,232,230,227,224,220,215,214,212,211,211,211,213,215,219,225,227,231,233,236,237,237,237,237,234,232,230,227,225,224,223,221,221,220,220,221,222,225,229,232,236,239,241,242,244,244,243,243,239,237,233,229,222,220,217,215,215,213,213,213,214,215,217,221,231,238,242,245,247,248,248,247,245,242,240,237,234,233,232,230,229,227,227,228,230,235,237,248,250,254,256,256,255,253,249,245,242,238,231,228,224,221,218,215,215,213,213,213,213,214,216,219,222,224,226,227,228,230,230,229,229,229,226,225,222,220,217,213,211,209,209,208,209,209,211,215,218,222,225,231,235,237,240,241,242,243,243,243,243,242,239,235,232,229,227,224,221,221,218,216,216,216,214,214,215,217,219,224,226,229,232,233,236,237,237,237,237,238,237,233,232,226,224,218,213,211,210,208,207,207,207,208,210,213,216,220,224,229,232,236,237,237,237,237,237,235,233,229,225,223,218,216,215,215,215,215,218,222,223,227,232,233,235,236,237,237,237,237,237,233,232,229,225,223,222,221,220,219,219,223,225,227,231,232,233,233,233,233,233,233,233,231,230,228,226,226,226,228,231,233,236,238,239,241,243,243,242,240,238,234,232,231,229,227,226,225,225,225,225,226,230,234,236,241,244,247,249,251,251,252,252,252,248,245,243,239,236,234,231,229,227,227,227,227,230,230,234,237,242,244,246,247,248,248,248,248,247,246,243,240,238,233,231,228,227,225,224,224,224,224,225,230,234,237,241,243,246,248,249,249,248,248,244,243,239,236,234,230,229,226,225,225,224,224,224,225,233,235,240,244,247,249,249,251,251,251,251,247,243,240,236,232,229,226,224,224,224,224,226,229,232,238,240,242,243,244,244,244,244,244,244,242,240,236,235,232,230,229,227,226,226,226,226,226,227,228,230,232,233,236,239,239,240,242,242,242,242,242,242,241,239,237,234,232,230,228,226,225,225,225,225,225,225,225,226,231,233,236,238,240,244,244,245,246,247,247,247,247,247,246,244,243,241,239,236,234,233,231,231,230,230,230,230,231,234,236,241,242,246,249,251,251,253,254,254,256,256,256,256,256,255,254,251,248,246,243,242,242,240,240,240,240,242,244,248,250,253,255,257,258,258,258,258,258,256,255,250,247,243,241,238,236,235,233,234,234,238,241,243,246,248,249,251,251,253,253,253,251,249,245,242,240,238,236,234,234,234,234,236,238,240,242,246,247,248,249,250,250,250,250,250,249,245,244,242,238,236,234,232,232,230,230,230,231,233,235,236,239,243,245,252,253,255,255,257,257,257,256,256,253,248,246,241,237,233,232,229,229,227,226,225,222,222,222,220,220,223,225,228,234,234,234,235,235,236,238,241,241,240,237,235,231,228,224,220,218,216,215,215,214,213,213,214,217,219,222,226,229,232,233,235,237,238,240,241,243,244,246,246,248,248,247,247,247,245,240,238,234,233,229,228,226,224,223,221,221,220,220,218,218,219,219,221,225,226,230,233,236,239,243,246,248,250,252,252,252,252,252,252,252,249,248,243,241,236,231,228,223,220,218,215,213,211,209,207,205,205,205,205,205,207,212,216,220,224,226,236,239,241,242,243,245,247,247,247,247,247,244,241,238,234,229,227,222,219,215,211,211,210,208,206,206,206,207,211,216,220,226,231,238,243,246,247,249,250,250,250,250,249,247,243,239,237,232,230,226,224,221,219,218,218,217,216,216,217,219,222,226,230,233,237,241,245,247,247,248,248,248,248,248,246,243,235,232,229,226,222,218,217,215,213,212,212,212,212,212,214,218,221,228,239,243,246,247,247,247,247,246,242,240,235,231,227,223,219,216,214,213,213,213,213,213,216,220,222,226,228,231,232,235,237,237,236,236,232,229,224,221,219,216,214,212,212,212,212,212,216,219,222,226,230,236,238,242,246,247,249,249,249,249,249,249,248,241,238,233,230,228,226,224,223,223,223,223,225,230,233,237,241,245,248,250,251,251,248,246,242,238,232,232,228,225,222,219,216,215,214,214,214,214,216,219,222,225,232,237,239,243,247,249,251,252,252,252,252,252,252,248,245,242,236,232,228,224,221,217,215,215,215,215,216,219,220,224,229,234,238,241,243,246,246,246,246,246,245,240,235,231,224,222,219,216,214,212,212,212,212,213,215,219,224,225,231,236,240,242,246,248,248,245,236,234,226,223,219,218,216,214,214,214,215,215,220,223,230,234,238,244,247,249,250,251,251,251,251,249,244,240,237,229,226,222,220,218,217,217,217,217,217,218,219,224,228,230,234,239,241,244,246,247,249,249,249,247,244,239,236,232,229,225,221,218,216,215,214,212,212,212,212,216,220,223,226,231,235,241,243,244,246,246,246,246,246,245,241,237,232,227,224,219,215,214,214,213,212,213,214,217,223,225,229,236,241,245,249,249,249,251,250,250,246,244,240,238,229,227,224,223,222,222,223,228,234,237,242,249,254,257,261,261,260,256,253,249,242,237,233,229,227,224,223,223,224,229,231,234,238,242,244,247,248,248,248,248,248,244,240,238,235,232,231,227,226,226,226,226,227,228,237,239,243,248,248,252,252,252,252,251,250,248,245,241,237,235,231,230,230,230,230,230,230,230,231,234,238,239,243,244,246,248,248,248,248,248,244,240,237,233,227,220,218,215,212,212,211,210,210,210,211,212,217,221,224,229,234,237,239,239,241,241,243,243,243,242,240,237,237,235,232,230,229,228,228,228,228,228,229,231,234,236,238,240,241,242,245,245,244,243,240,238,236,233,232,229,228,228,226,226,225,225,225,225,225,227,231,234,238,242,249,254,259,264,266,266,266,266,265,261,257,251,247,237,233,231,229,229,230,232,240,247,253,262,270,274,279,281,283,281,275,267,258,253,244,235,227,219,215,213,212,211,211,211,214,218,226,232,238,245,252,258,263,266,267,265,263,258,255,250,247,241,237,231,227,224,223,222,222,224,230,237,243,255,262,275,288,301,312,324,330,334,334,331,329,322,314,307,296,290,281,274,267,260,255,251,250,248,248,248,248,250,250,254,256,263,267,271,275,279,282,284,283,279,276,270,264,255,250,240,234,229,224,221,219,219,221,224,226,230,235,239,245,250,252,253,252,252,247,245,242,236,232,224,223,223,223,223,223,226,230,234,238,242,246,248,250,251,251,251,250,247,244,239,236,234,229,227,227,229,233,239,246,253,262,274,290,297,307,316,322,328,333,339,344,347,353,357,363,366,373,376,382,386,390,393,394,396,396,396,392,389,382,377,373,361,354,347,334,327,317,304,294,286,275,267,259,254,247,239,233,229,227,224,221,220,218,217,215,214,213,211,209,206,205,204,201,201,200,200,200,198,198,198,199,201,203,206,207,211,213,214,219,220,223,228,230,232,234,236,237,238,241,242,242,242,242,242,241,237,236,234,233,230,229,228,228,228,228,228,230,231,234,235,237,239,240,242,243,243,243,243,243,239,236,233,229,225,224,221,219,218,218,218,218,220,222,225,228,231,235,236,237,239,239,239,238,237,234,231,228,225,221,219,217,214,213,213,213,213,214,217,220,223,229,233,238,239,243,245,245,245,245,244,243,238,234,230,225,220,216,213,209,208,207,207,208,211,215,218,220,221,224,225,225,221,217,215,212,210,207,205,205,210,214,215,220,222,227,233,237,242,243,245,246,246,243,243,239,236,232,227,223,214,210,209,204,201,198,195,193,189,186,183,179,176,171,166,160,153,143,136,131,121,116,114,108,106,103,101,100,100,101,104,108,116,120,124,132,136,143,154,161,171,179,183,187,191,194,197,199,203,205,210,215,219,223,226,231,235,239,244,248,252,251,251,251,251,251,251,252,253,253,253,248,245,241,235,231,224,220,217,215,213,213,213,213,216,218,222,226,230,234,237,239,239,239,238,235,232,231,227,223,219,216,214,210,208,208,208,208,209,211,214,217,221,224,226,229,231,234,236,236,235,231,227,223,220,217,215,210,205,204,202,201,201,201,201,202,204,207,211,217,221,225,230,234,236,238,242,242,242,242,238,233,229,227,222,219,214,211,208,207,207,207,205,205,206,208,210,216,219,226,233,236,240,242,243,243,243,242,240,236,229,222,218,210,206,196,193,192,190,190,191,193,198,205,212,219,221,228,232,236,238,238,238,238,235,231,227,221,216,209,205,201,199,198,197,198,199,201,207,212,218,220,229,231,235,236,238,238,237,235,231,226,217,212,206,201,199,195,195,194,194,194,195,195,199,203,205,209,212,215,218,219,220,220,220,219,218,215,214,211,210,208,207,207,205,205,205,205,205,206,208,210,212,214,216,220,223,225,227,227,227,227,227,225,224,220,218,215,213,212,210,209,210,213,217,221,226,229,233,238,242,243,245,245,245,247,245,243,230,225,218,213,208,202,197,194,190,188,188,186,186,186,187,190,197,201,206,209,214,217,220,226,231,233,233,234,234,233,230,225,223,221,215,212,207,205,202,202,202,202,202,204,206,211,216,221,223,228,230,233,235,235,235,235,235,234,228,224,219,215,210,205,202,201,199,199,199,199,199,203,205,211,215,219,223,227,233,235,238,239,239,239,239,236,233,230,227,224,220,218,215,212,210,210,210,213,216,220,226,231,236,243,247,249,252,253,253,253,248,245,240,234,227,222,216,211,209,205,203,203,203,203,207,209,214,216,220,223,226,229,233,235,236,238,238,238,237,232,229,226,221,216,212,206,203,200,200,200,200,200,200,204,208,212,214,218,222,226,227,231,232,234,234,234,234,234,234,234,233,229,224,220,217,213,209,207,200,200,198,198,199,199,203,207,213,216,222,227,233,238,241,242,242,242,242,242,237,233,228,212,205,197,193,191,189,187,187,186,186,189,193,198,202,207,220,224,227,230,232,232,232,230,226,223,220,215,208,204,199,197,195,192,192,192,193,197,200,212,213,221,225,227,230,231,233,233,233,232,232,228,226,221,217,213,208,206,202,200,198,198,198,200,202,206,212,214,220,223,227,230,231,233,233,233,233,233,233,230,227,221,217,213,210,207,204,202,202,201,201,201,202,205,209,213,217,221,223,224,225,225,225,225,224,223,219,214,210,205,201,199,195,193,193,191,191,191,191,194,198,202,206,211,216,221,224,226,228,228,229,229,228,227,223,221,216,214,210,204,203,199,197,197,197,197,198,205,209,212,215,220,224,229,231,234,235,237,237,237,237,237,233,231,228,225,222,218,216,213,211,210,208,208,208,208,212,215,218,222,226,230,231,235,237,238,238,238,238,237,235,232,228,224,220,215,211,210,208,207,207,207,208,208,211,216,222,226,231,238,241,244,247,249,249,249,249,244,238,233,228,222,218,215,211,208,206,206,206,206,206,207,208,210,213,218,222,225,228,231,235,239,240,240,242,240,239,238,233,227,222,216,209,207,202,198,197,195,194,192,192,192,193,195,200,205,212,218,222,228,232,236,237,239,239,238,237,233,230,224,219,216,207,204,199,197,196,196,196,196,196,196,199,204,210,214,217,221,225,228,231,232,232,231,229,226,222,219,214,212,207,202,198,196,194,194,194,194,194,194,194,196,200,204,210,213,217,222,225,229,233,235,236,236,236,236,235,232,226,222,219,212,208,206,201,200,199,199,199,199,200,202,206,212,214,216,220,222,225,227,227,227,227,227,226,226,224,221,218,215,213,209,208,206,205,205,205,205,206,209,210,217,219,222,225,228,231,232,233,233,233,233,232,230,227,224,220,217,211,206,203,199,198,196,195,195,195,195,197,200,210,213,215,218,219,221,222,224,224,223,221,219,216,213,211,209,206,203,202,201,200,200,198,198,199,201,201,203,205,206,208,209,209,209,209,211,213,214,217,219,221,223,224,226,226,226,226,225,223,222,219,215,213,211,207,205,203,202,201,201,201,201,201,202,204,205,205,207,210,212,213,215,217,218,218,218,219,220,220,218,215,212,209,205,203,198,196,195,191,191,189,189,189,189,189,190,192,195,204,207,211,213,216,220,222,224,225,227,227,228,229,230,230,230,230,230,230,229,228,227,224,220,219,218,216,213,212,211,210,209,209,207,207,207,207,207,207,208,209,210,213,215,221,224,227,230,232,232,232,231,229,227,223,221,220,216,213,211,207,204,202,199,197,195,194,192,192,190,190,189,189,189,190,191,192,194,196,198,200,201,203,205,206,208,209,210,212,213,215,217,218,219,222,224,226,226,226,226,226,225,222,219,218,215,213,211,206,204,200,198,197,197,197,195,193,193,193,193,193,193,193,193,193,193,193,194,196,197,198,199,199,201,203,204,207,210,213,215,217,219,221,223,224,226,228,229,229,229,230,231,231,230,228,227,226,219,217,213,212,210,207,204,202,200,198,198,195,194,194,193,192,190,190,190,191,191,191,191,191,193,194,195,198,200,202,205,206,208,210,212,213,215,216,217,219,220,220,222,222,222,222,222,222,222,222,222,222,222,220,219,217,215,213,212,211,209,208,206,206,205,203,203,202,202,200,200,199,197,197,196,196,196,196,196
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Simulation/SimulationCSVData/TestElEnc.csv b/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Simulation/SimulationCSVData/TestElEnc.csv
new file mode 100644
index 00000000..097a7535
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Simulation/SimulationCSVData/TestElEnc.csv
@@ -0,0 +1 @@
+7,7,7,7,7,7,9,11,11,11,11,11,12,13,13,13,15,15,17,17,17,18,18,20,21,21,23,23,24,25,26,27,27,29,31,32,34,35,37,37,38,40,42,43,44,45,46,48,49,51,51,53,54,56,56,57,59,61,61,64,64,66,67,69,70,70,72,74,75,75,77,77,78,78,80,80,81,82,82,83,83,85,85,86,87,88,88,88,89,89,89,89,91,91,91,91,91,91,91,89,89,89,89,88,87,86,86,85,85,83,83,82,82,81,80,80,79,77,77,76,74,72,72,71,70,68,66,62,61,61,59,57,57,55,54,53,53,52,50,50,48,46,45,43,42,41,40,39,37,35,33,32,32,30,30,30,28,28,27,27,27,27,25,25,24,23,22,22,21,21,19,19,17,17,16,16,16,14,14,14,14,12,12,12,12,12,11,11,9,9,9,9,9,8,7,7,7,7,7,7,7,7,7,7,7,7,7,8,8,8,10,10,10,11,11,12,13,13,13,14,14,16,18,18,18,19,21,23,23,23,24,26,26,27,27,27,29,29,31,31,32,32,33,34,35,36,38,40,41,43,44,44,46,48,48,49,49,51,51,52,52,54,54,56,57,57,59,59,61,61,62,62,62,64,64,65,65,65,67,67,67,69,69,70,70,72,72,73,73,74,75,75,77,77,77,78,80,80,80,80,81,81,81,83,83,84,84,85,86,86,86,86,87,87,87,87,87,87,85,85,84,84,84,84,84,84,84,84,84,84,84,84,83,82,81,81,81,79,77,77,76,74,72,71,69,67,66,64,62,61,59,59,58,58,56,54,53,51,51,50,50,48,46,46,45,43,41,41,40,38,37,37,35,34,34,33,32,31,31,29,29,28,28,26,25,25,23,21,21,21,20,18,18,18,16,15,15,13,13,11,11,11,10,10,9,8,8,8,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,8,9,9,10,10,10,12,12,12,12,14,14,14,15,16,17,17,18,18,19,20,21,21,23,23,24,25,26,27,27,29,30,31,32,34,36,37,37,38,38,40,40,41,43,44,45,46,47,48,48,49,49,50,51,52,52,54,54,56,58,58,59,61,62,62,64,64,64,65,65,65,67,67,68,68,69,70,70,71,71,72,73,74,74,75,75,76,77,77,78,78,80,80,80,80,80,82,82,82,82,82,82,82,82,82,82,82,82,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,81,81,79,79,79,78,78,76,76,75,75,73,73,71,70,68,66,65,64,63,62,61,60,59,59,59,57,56,54,54,52,50,50,49,49,47,47,46,44,44,42,41,41,41,39,39,38,36,34,33,33,31,31,30,30,28,28,28,26,25,23
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Simulation/SimulationCSVData/TestElTemp.csv b/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Simulation/SimulationCSVData/TestElTemp.csv
new file mode 100644
index 00000000..575b0691
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Simulation/SimulationCSVData/TestElTemp.csv
@@ -0,0 +1 @@
+13,11,11,11,11,11,11,11,11,11,11,12,12,12,12,13,13,13,13,15,15,15,16,16,17,18,18,18,18,18,19,19,19,19,21,21,21,21,21,21,21,23,23,23,23,23,23,23,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,26,26,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,28,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,32,32,32,32,32,32,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,31,31,31,31,31,31,31,31,31,31,29,29,29,29,29,29,29,28,28,26,26,26,26,24,24,23,23,23,23,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,23,23,23,23,22,22,23,23,22,22,22,22,22,22,22,22,22,21,21,21,21,21,21,21,21,21,19,19,17,17,17,17,17,17,17,17,17,17,17,17,17,17,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,18,18,18,19,19,19,21,21,21,21,21,21,21,21,22,22,22,22,22,22,22,22,22,24,24,24,24,24,24,24,24,24,24,24,24,24,24,26,26,26,26,26,27,27,29,29,29,29,31,31,31,31,31,32,32,32,33,34,34,35,35,35,35,36,37,36,36,36,36,36,37,37,36,36,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,36,36,36,36,36,36,36,36,36,36,36,35,35,35,35,35,33,33,33,32,32,32,32
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Simulation/SimulationSensorNetwork.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Simulation/SimulationSensorNetwork.cs
new file mode 100644
index 00000000..0b0fec4b
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Simulation/SimulationSensorNetwork.cs
@@ -0,0 +1,519 @@
+using ControlRoomApplication.Util;
+using EmbeddedSystemsTest.SensorNetworkSimulation;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Net.Sockets;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace ControlRoomApplication.Controllers.SensorNetwork.Simulation
+{
+ ///
+ /// The simulation sensor network, which will respond exactly the same was as the physical SensorNetwork hardware will. The SensorNetworkServer
+ /// does not know the difference between this and the physical hardware.
+ ///
+ public class SimulationSensorNetwork : PacketEncodingTools
+ {
+ private static readonly log4net.ILog logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
+
+ ///
+ /// Constructor to initialize a new instance of the SimulationSensorNetwork. This will NOT start its simulated sensor monitoring.
+ ///
+ /// The Teensy's Client IP; this must be set equal to the SensorNetworkServer's Server IP.
+ /// The Teensy's Client Port; this must be set equal to the SensorNetworkServer's Server Port.
+ /// The Teensy's Server IP; this must be set equal to the SensorNetworkServer's Client IP.
+ /// The Teensy's Server Port; this must be set equal to the SensorNetworkServer's Client Port.
+ /// The path to CSV data. By default, it looks for it in the SensorNetworkConstants.SimCSVDirectory location.
+ public SimulationSensorNetwork(string teensyClientIP, int teensyClientPort, IPAddress teensyServerIP, int teensyServerPort, string dataPath = SensorNetworkConstants.SimCSVDirectory)
+ {
+ Server = new TcpListener(teensyServerIP, teensyServerPort);
+
+ ClientIP = teensyClientIP;
+ ClientPort = teensyClientPort;
+
+ DataDirectory = dataPath;
+ }
+
+ private TcpListener Server { get; set; }
+ private NetworkStream ServerStream { get; set; }
+
+ private TcpClient Client { get; set; }
+ private string ClientIP { get; set; }
+ private int ClientPort { get; set; }
+ private NetworkStream ClientStream { get; set; }
+
+ private string DataDirectory;
+
+ private Thread SimulationSensorMonitoringThread { get; set; }
+
+ private bool CurrentlyRunning { get; set; }
+
+ private double[] AzimuthTempData { get; set; }
+
+ private double[] ElevationTempData { get; set; }
+
+ private RawAccelerometerData[] AzimuthAccData { get; set; }
+
+ private RawAccelerometerData[] ElevationAccData { get; set; }
+
+ private RawAccelerometerData[] CounterbalanceAccData { get; set; }
+
+ private double[] AzimuthEncoderData { get; set; }
+
+ private double[] ElevationEncoderData { get; set; }
+
+ private long ConnectionTimeStamp { get; set; }
+
+ ///
+ /// This is used to start the simulation Sensor Network. Calling this is equivalent to powering on the Teensy.
+ ///
+ public void StartSimulationSensorNetwork()
+ {
+ CurrentlyRunning = true;
+ SimulationSensorMonitoringThread = new Thread(() => { SimulationSensorMonitor(); });
+ SimulationSensorMonitoringThread.Start();
+ }
+
+ ///
+ /// This is used to start the simulation Sensor Network. Calling this is equivalent to powering off the Teensy.
+ ///
+ public void EndSimulationSensorNetwork()
+ {
+ if (CurrentlyRunning)
+ {
+ CurrentlyRunning = false;
+ if (Client != null) Client.Dispose();
+ if (ClientStream != null)
+ {
+ ClientStream.Close();
+ ClientStream.Dispose();
+ }
+ Server.Stop();
+ if (ServerStream != null)
+ {
+ ServerStream.Close();
+ ServerStream.Dispose();
+ }
+ SimulationSensorMonitoringThread.Join();
+ }
+ }
+
+ private void SimulationSensorMonitor()
+ {
+ // First, we want to connect to the SensorNetworkServer
+ if(CurrentlyRunning) WaitForAndConnectToServer();
+
+ // Next, we want to request initialization and receive it
+ byte[] receivedInit = new byte[0];
+ if(CurrentlyRunning) receivedInit = RequestAndAcquireSensorInitialization();
+
+ ConnectionTimeStamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
+
+ // At this point, we have the initialization and can initialize the sensors
+ if (CurrentlyRunning) InitializeSensors(receivedInit);
+
+ // Now we can grab the CSV data for ONLY the initialized sensors...
+ if(CurrentlyRunning) ReadFakeDataFromCSV();
+
+ // Keep track of the indexes for each data array, because we are only extracting a small subsection of each one.
+ // We want to know what subsection we just got so we can get the next subsection in the next iteration
+ int? elTempIdx = 0;
+ int? azTempIdx = 0;
+ int? elEncIdx = 0;
+ int? azEncIdx = 0;
+ int? elAccIdx = 0;
+ int? azAccIdx = 0;
+ int? cbAccIdx = 0;
+
+ // This will tell us if we are rebooting or not. We will only reboot if the connection is randomly terminated.
+ bool reboot = false;
+
+ // Now we enter the "super loop"
+ while (CurrentlyRunning)
+ {
+ // Convert subarrays to bytes
+ SimulationSubArrayData subArrays = BuildSubArrays(ref elTempIdx, ref azTempIdx, ref elEncIdx, ref azEncIdx, ref elAccIdx, ref azAccIdx, ref cbAccIdx);
+
+ SensorStatuses statuses = new SensorStatuses
+ {
+ // TODO: Write the values of each sensor status in here so it can get be encoded (issue #376)
+ };
+
+ byte[] dataToSend = ConvertDataArraysToBytes(
+ subArrays.ElevationAccl,
+ subArrays.AzimuthAccl,
+ subArrays.CounterBAccl,
+ subArrays.ElevationTemps,
+ subArrays.AzimuthTemps,
+ subArrays.ElevationEnc,
+ subArrays.AzimuthEnc,
+ statuses,
+ ConnectionTimeStamp
+ );
+
+ // We have to check for CurrentlyRunning down here because we don't know when the connection is going to be terminated, and
+ // it could very well be in the middle of the loop.
+ if (CurrentlyRunning)
+ {
+ try
+ {
+ // Send arrays
+ ClientStream.Write(dataToSend, 0, dataToSend.Length);
+ Thread.Sleep(SensorNetworkConstants.DataSendingInterval);
+ }
+ // This will be reached if the connection is unexpectedly terminated (like it is during sensor reinitialization)
+ catch
+ {
+ CurrentlyRunning = false;
+ reboot = true;
+ }
+ }
+ }
+
+ // If the server disconnects, that triggers a reboot
+ if(reboot)
+ {
+ CurrentlyRunning = true;
+ Client.Dispose();
+ ClientStream.Dispose();
+ SimulationSensorMonitor();
+ }
+ }
+
+ ///
+ /// This will read into each data array and pull out a subarray based on the index value, and then encode those subarrays.
+ ///
+ /// Azimuth temperature data array index that we are pulling from.
+ /// Elevation temperature data array index that we are pulling from.
+ /// Elevation encoder data array index that we are pulling from.
+ /// Azimuth encoder data array index that we are pulling from.
+ /// Elevation accelerometer data array index that we are pulling from.
+ /// Azimuth accelerometer data array index that we are pulling from.
+ /// Counterbalance accelerometer data array index that we are pulling from.
+ ///
+ public SimulationSubArrayData BuildSubArrays(ref int? elTempIdx, ref int? azTempIdx, ref int? elEncIdx, ref int? azEncIdx, ref int? elAccIdx, ref int? azAccIdx, ref int? cbAccIdx)
+ {
+ SimulationSubArrayData subArrays = new SimulationSubArrayData();
+
+ // If the sensors are initialized, give them their subarrays, while also updating the index so that
+ // this knows what subarrays to go to next
+
+ if (ElevationTempData != null && elTempIdx != null)
+ {
+ subArrays.ElevationTemps = new double[1];
+ Array.Copy(ElevationTempData, elTempIdx ?? 0, subArrays.ElevationTemps, 0, 1);
+
+ // Increment to next index, or back to 0 if we've reached the end of the main array
+ if (elTempIdx + 1 > ElevationTempData.Length - 1) elTempIdx = 0;
+ else elTempIdx++;
+ }
+ else subArrays.ElevationTemps = new double[0];
+
+ if (AzimuthTempData != null && azTempIdx != null)
+ {
+ subArrays.AzimuthTemps = new double[1];
+ Array.Copy(AzimuthTempData, azTempIdx ?? 0, subArrays.AzimuthTemps, 0, 1);
+
+ // Increment to next index, or back to 0 if we've reached the end of the main array
+ if (azTempIdx + 1 > AzimuthTempData.Length - 1) azTempIdx = 0;
+ else azTempIdx++;
+ }
+ else subArrays.AzimuthTemps = new double[0];
+
+ if (ElevationEncoderData != null && elEncIdx != null)
+ {
+ subArrays.ElevationEnc = new double[1];
+ Array.Copy(ElevationEncoderData, elEncIdx ?? 0, subArrays.ElevationEnc, 0, 1);
+
+ // Increment to next index, or back to 0 if we've reached the end of the main array
+ if (elEncIdx + 1 > ElevationEncoderData.Length - 1) elEncIdx = 0;
+ else elEncIdx++;
+ }
+ else subArrays.ElevationEnc = new double[0];
+
+ if (AzimuthEncoderData != null && azEncIdx != null)
+ {
+ subArrays.AzimuthEnc = new double[1];
+ Array.Copy(AzimuthEncoderData, azEncIdx ?? 0, subArrays.AzimuthEnc, 0, 1);
+
+ // Increment to next index, or back to 0 if we've reached the end of the main array
+ if (azEncIdx + 1 > AzimuthEncoderData.Length - 1) azEncIdx = 0;
+ else azEncIdx++;
+ }
+ else subArrays.AzimuthEnc = new double[0];
+
+ if (AzimuthAccData != null && azAccIdx != null)
+ {
+ subArrays.AzimuthAccl = new RawAccelerometerData[100];
+ Array.Copy(AzimuthAccData, azAccIdx ?? 0, subArrays.AzimuthAccl, 0, 100);
+
+ // Increment to next index, or back to 0 if we've reached the end of the main array
+ if (azAccIdx + 199 > AzimuthAccData.Length - 1) azAccIdx = 0;
+ else azAccIdx += 100;
+ }
+ else subArrays.AzimuthAccl = new RawAccelerometerData[0];
+
+ if (ElevationAccData != null && elAccIdx != null)
+ {
+ subArrays.ElevationAccl = new RawAccelerometerData[100];
+ Array.Copy(ElevationAccData, elAccIdx ?? 0, subArrays.ElevationAccl, 0, 100);
+
+ // Increment to next index, or back to 0 if we've reached the end of the main array
+ if (elAccIdx + 199 > ElevationAccData.Length - 1) elAccIdx = 0;
+ else elAccIdx += 100;
+ }
+ else subArrays.ElevationAccl = new RawAccelerometerData[0];
+
+ if (CounterbalanceAccData != null && cbAccIdx != null)
+ {
+ subArrays.CounterBAccl = new RawAccelerometerData[100];
+ Array.Copy(CounterbalanceAccData, cbAccIdx ?? 0, subArrays.CounterBAccl, 0, 100);
+
+ // Increment to next index, or back to 0 if we've reached the end of the main array
+ if (cbAccIdx + 199 > CounterbalanceAccData.Length - 1) cbAccIdx = 0;
+ else cbAccIdx += 100;
+ }
+ else subArrays.CounterBAccl = new RawAccelerometerData[0];
+
+ return subArrays;
+ }
+
+ ///
+ /// This will wait for the SensorNetworkServer, and when it finds it, it will connect!
+ /// This code was directly lifted from how this functionality works in the Teensy's source code.
+ ///
+ private void WaitForAndConnectToServer()
+ {
+ bool connected = false;
+
+ // Wait for the SensorNetworkServer to be up
+ while (!connected && CurrentlyRunning)
+ {
+ try
+ {
+ Client = new TcpClient(ClientIP, ClientPort);
+ ClientStream = Client.GetStream();
+ connected = true;
+
+ // Ask the SensorNetworkServer for its initialization
+ byte[] askForInit = Encoding.ASCII.GetBytes("Send Sensor Configuration");
+ ClientStream.Write(askForInit, 0, askForInit.Length);
+ ClientStream.Flush();
+ }
+ catch
+ {
+ logger.Info($"{Utilities.GetTimeStamp()}: SimulationSensorNetwork is waiting for the SensorNetworkServer.");
+ if (Client != null) Client.Dispose();
+ if (ClientStream != null) ClientStream.Dispose();
+ }
+ }
+ }
+
+ ///
+ /// This will send a request for sensor initialization to the SensorNetworkServer, where the
+ /// SensorNetworkServer will then respond with sensor initialization.
+ ///
+ /// The sensor initialization byte array.
+ private byte[] RequestAndAcquireSensorInitialization()
+ {
+ // Start the server that will expect the Sensor Configuration
+ Server.Start();
+
+ // Wait for the SensorNetworkClient to send the initialization
+ TcpClient localClient;
+ byte[] receivedInit = new byte[SensorNetworkConstants.SensorNetworkSensorCount];
+
+ // Once this line is passed, we have connected and received the initialization
+ localClient = Server.AcceptTcpClient();
+ logger.Info($"{Utilities.GetTimeStamp()}: Simulation Sensor Network received Sensor Initialization");
+ ServerStream = localClient.GetStream();
+ ServerStream.Read(receivedInit, 0, receivedInit.Length);
+
+ // We will now dispose of the Server/Stream components because that is the only time we are using it
+ ServerStream.Close();
+ ServerStream.Dispose();
+ Server.Stop();
+
+ return receivedInit;
+ }
+
+ ///
+ /// This is used to set the initialization of the sensors. Any non-initialized sensors will not be encoded.
+ ///
+ /// Sensor initialization we receive from the SensorNetworkServer's InitializationClient
+ private void InitializeSensors(byte[] init)
+ {
+ if (init[(int)SensorInitializationEnum.ElevationTemp] == 0) ElevationTempData = null;
+ else ElevationTempData = new double[0];
+
+ if (init[(int)SensorInitializationEnum.AzimuthTemp] == 0) AzimuthTempData = null;
+ else AzimuthTempData = new double[0];
+
+ if (init[(int)SensorInitializationEnum.ElevationEncoder] == 0) ElevationEncoderData = null;
+ else ElevationEncoderData = new double[0];
+
+ if (init[(int)SensorInitializationEnum.AzimuthEncoder] == 0) AzimuthEncoderData = null;
+ else AzimuthEncoderData = new double[0];
+
+ if (init[(int)SensorInitializationEnum.AzimuthAccelerometer] == 0) AzimuthAccData = null;
+ else AzimuthAccData = new RawAccelerometerData[0];
+
+ if (init[(int)SensorInitializationEnum.ElevationAccelerometer] == 0) ElevationAccData = null;
+ else ElevationAccData = new RawAccelerometerData[0];
+
+ if (init[(int)SensorInitializationEnum.CounterbalanceAccelerometer] == 0) CounterbalanceAccData = null;
+ else CounterbalanceAccData = new RawAccelerometerData[0];
+ }
+
+ ///
+ /// This will read fake data from the CSV files based off of the initialization. If the sensor is "initialized" (not null),
+ /// then it will read in CSV data for it. Otherwise, it will stay null.
+ ///
+ private void ReadFakeDataFromCSV()
+ {
+ if (ElevationTempData != null)
+ {
+ double dbl;
+
+ var values = File.ReadAllLines(DataDirectory + "TestElTemp.csv")
+ .SelectMany(a => a.Split(',')
+ .Select(str => double.TryParse(str, out dbl) ? dbl : 0));
+
+ ElevationTempData = values.ToArray();
+ }
+
+ if (AzimuthTempData != null)
+ {
+ double dbl;
+
+ var values = File.ReadAllLines(DataDirectory + "TestAzTemp.csv")
+ .SelectMany(a => a.Split(',')
+ .Select(str => double.TryParse(str, out dbl) ? dbl : 0));
+
+ AzimuthTempData = values.ToArray();
+ }
+
+ if (AzimuthAccData != null)
+ {
+ int tempInt;
+
+ int[] xData = File.ReadAllLines(DataDirectory + "TestAzAccX.csv")
+ .SelectMany(a => a.Split(',')
+ .Select(str => int.TryParse(str, out tempInt) ? tempInt : 0)).ToArray();
+
+ int[] yData = File.ReadAllLines(DataDirectory + "TestAzAccY.csv")
+ .SelectMany(a => a.Split(',')
+ .Select(str => int.TryParse(str, out tempInt) ? tempInt : 0)).ToArray();
+
+ int[] zData = File.ReadAllLines(DataDirectory + "TestAzAccZ.csv")
+ .SelectMany(a => a.Split(',')
+ .Select(str => int.TryParse(str, out tempInt) ? tempInt : 0)).ToArray();
+
+ // Find which axis has the lowest number, which we will use as the size for the overall array
+ int lowest = xData.Length;
+ if (lowest > yData.Length) lowest = yData.Length;
+ if (lowest > zData.Length) lowest = zData.Length;
+
+ AzimuthAccData = new RawAccelerometerData[lowest];
+
+ // Populate raw accelerometer data with individual axes
+ for(int i = 0; i < lowest; i++)
+ {
+ AzimuthAccData[i].X = xData[i];
+ AzimuthAccData[i].Y = yData[i];
+ AzimuthAccData[i].Z = zData[i];
+ }
+ }
+
+ if (ElevationAccData != null)
+ {
+ int tempInt;
+
+ int[] xData = File.ReadAllLines(DataDirectory + "TestElAccX.csv")
+ .SelectMany(a => a.Split(',')
+ .Select(str => int.TryParse(str, out tempInt) ? tempInt : 0)).ToArray();
+
+ int[] yData = File.ReadAllLines(DataDirectory + "TestElAccY.csv")
+ .SelectMany(a => a.Split(',')
+ .Select(str => int.TryParse(str, out tempInt) ? tempInt : 0)).ToArray();
+
+ int[] zData = File.ReadAllLines(DataDirectory + "TestElAccZ.csv")
+ .SelectMany(a => a.Split(',')
+ .Select(str => int.TryParse(str, out tempInt) ? tempInt : 0)).ToArray();
+
+ // Find which axis has the lowest number, which we will use as the size for the overall array
+ int lowest = xData.Length;
+ if (lowest > yData.Length) lowest = yData.Length;
+ if (lowest > zData.Length) lowest = zData.Length;
+
+ ElevationAccData = new RawAccelerometerData[lowest];
+
+ // Populate raw accelerometer data with individual axes
+ for (int i = 0; i < lowest; i++)
+ {
+ ElevationAccData[i].X = xData[i];
+ ElevationAccData[i].Y = yData[i];
+ ElevationAccData[i].Z = zData[i];
+ }
+ }
+
+ if (CounterbalanceAccData != null)
+ {
+ int tempInt;
+
+ int[] xData = File.ReadAllLines(DataDirectory + "TestCbAccX.csv")
+ .SelectMany(a => a.Split(',')
+ .Select(str => int.TryParse(str, out tempInt) ? tempInt : 0)).ToArray();
+
+ int[] yData = File.ReadAllLines(DataDirectory + "TestCbAccY.csv")
+ .SelectMany(a => a.Split(',')
+ .Select(str => int.TryParse(str, out tempInt) ? tempInt : 0)).ToArray();
+
+ int[] zData = File.ReadAllLines(DataDirectory + "TestCbAccZ.csv")
+ .SelectMany(a => a.Split(',')
+ .Select(str => int.TryParse(str, out tempInt) ? tempInt : 0)).ToArray();
+
+ // Find which axis has the lowest number, which we will use as the size for the overall array
+ int lowest = xData.Length;
+ if (lowest > yData.Length) lowest = yData.Length;
+ if (lowest > zData.Length) lowest = zData.Length;
+
+ CounterbalanceAccData = new RawAccelerometerData[lowest];
+
+ // Populate raw accelerometer data with individual axes
+ for (int i = 0; i < lowest; i++)
+ {
+ CounterbalanceAccData[i].X = xData[i];
+ CounterbalanceAccData[i].Y = yData[i];
+ CounterbalanceAccData[i].Z = zData[i];
+ }
+ }
+
+ if (ElevationEncoderData != null)
+ {
+ double dbl;
+
+ var values = File.ReadAllLines(DataDirectory + "TestElEnc.csv")
+ .SelectMany(a => a.Split(',')
+ .Select(str => double.TryParse(str, out dbl) ? dbl : 0));
+
+ ElevationEncoderData = values.ToArray();
+ }
+
+ if (AzimuthEncoderData != null)
+ {
+ double dbl;
+
+ var values = File.ReadAllLines(DataDirectory + "TestAzEnc.csv")
+ .SelectMany(a => a.Split(',')
+ .Select(str => double.TryParse(str, out dbl) ? dbl : 0));
+
+ AzimuthEncoderData = values.ToArray();
+ }
+ }
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Simulation/SimulationSubArrayData.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Simulation/SimulationSubArrayData.cs
new file mode 100644
index 00000000..5f4e395d
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/SensorNetwork/Simulation/SimulationSubArrayData.cs
@@ -0,0 +1,50 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ControlRoomApplication.Controllers.SensorNetwork.Simulation
+{
+ ///
+ /// This references all the simulated sensors that the SimulatedSensorNetwork uses.
+ /// It holds the data that it is sending to the SensorNetworkServer at a given time.
+ ///
+ public struct SimulationSubArrayData
+ {
+ ///
+ /// Sub array of elevation temperatures.
+ ///
+ public double[] ElevationTemps { get; set; }
+
+ ///
+ /// Sub array of azimuth temperatures.
+ ///
+ public double[] AzimuthTemps { get; set; }
+
+ ///
+ /// Sub array of elevation accelerometer data.
+ ///
+ public RawAccelerometerData[] ElevationAccl { get; set; }
+
+ ///
+ /// Sub array of azimuth accelerometer data.
+ ///
+ public RawAccelerometerData[] AzimuthAccl { get; set; }
+
+ ///
+ /// Sub array of counterbalance accelerometer data.
+ ///
+ public RawAccelerometerData[] CounterBAccl { get; set; }
+
+ ///
+ /// Sub array of elevation encoder data.
+ ///
+ public double[] ElevationEnc { get; set; }
+
+ ///
+ /// Sub array of azimuth encoder data.
+ ///
+ public double[] AzimuthEnc { get; set; }
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/Sensors/AbstractTemperatureSensor.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/Sensors/AbstractTemperatureSensor.cs
deleted file mode 100644
index 0c5eb997..00000000
--- a/ControlRoomApplication/ControlRoomApplication/Controllers/Sensors/AbstractTemperatureSensor.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace ControlRoomApplication.Controllers.Sensors
-{
- ///
- /// Abstract class for the temperature sensor
- ///
- ///
- public abstract class AbstractTemperatureSensor
- {
- ///
- /// get temperature of elevation motor
- ///
- ///
- public abstract double GetElevationTemperature();
-
- ///
- /// get temperature of azimuth temperature
- ///
- ///
- public abstract double GetAzimuthTemperature();
-
- ///
- ///
- ///
- ///
- // public abstract void SetElevationTemperature();
-
- ///
- ///
- ///
- ///
- //public abstract void SetAzimuthTemperature();
-
-
-
-
-
-
-
- }
-}
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/Sensors/FakeEncoderSensor.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/Sensors/FakeEncoderSensor.cs
new file mode 100644
index 00000000..d730090b
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/Sensors/FakeEncoderSensor.cs
@@ -0,0 +1,95 @@
+using ControlRoomApplication.Controllers.Sensors;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using ControlRoomApplication.Constants;
+
+namespace ControlRoomApplication.Simulators.Hardware
+{
+
+ class FakeEncoderSensor
+ {
+ double _elAngle = 0.0;
+ double _azAngle = 0.0;
+ bool upOrDown = true; // Up is true, down is false
+ bool leftOrRight = true; // Right is true, left is false
+ DateTime currentElevationTime = DateTime.Now;
+ DateTime currentAzimuthTime = DateTime.Now;
+
+ public double GetElevationAngle()
+ {
+ if (_elAngle < SimulationConstants.MIN_ELEVATION_ANGLE)
+ upOrDown = true;
+ else if (_elAngle > SimulationConstants.MAX_ELEVATION_ANGLE)
+ upOrDown = false;
+
+ return ReadElevationAngleDemo();
+ }
+
+ public double GetAzimuthAngle()
+ {
+ if (_azAngle < SimulationConstants.MIN_AZIMUTH_ANGLE)
+ leftOrRight = true;
+ else if (_azAngle > SimulationConstants.MAX_AZIMUTH_ANGLE)
+ leftOrRight = false;
+
+ return ReadAzimuthAngleDemo();
+ }
+
+ public double ReadElevationAngleDemo()
+ {
+ TimeSpan elapsedElevationTime = DateTime.Now - currentElevationTime;
+ if (elapsedElevationTime.TotalSeconds > 1)
+ {
+ if (upOrDown)
+ _elAngle += SimulationConstants.ELEVATION_UPDATE_RATE;
+ else
+ _elAngle -= SimulationConstants.ELEVATION_UPDATE_RATE;
+
+ currentElevationTime = DateTime.Now;
+ }
+
+ return _elAngle;
+
+ }
+
+ public double ReadAzimuthAngleDemo()
+ {
+ TimeSpan elapsedAzimuthTime = DateTime.Now - currentAzimuthTime;
+ if (elapsedAzimuthTime.TotalSeconds > 1)
+ {
+ if (leftOrRight)
+ _azAngle += SimulationConstants.AZIMUTH_UPDATE_RATE;
+ else
+ _azAngle -= SimulationConstants.AZIMUTH_UPDATE_RATE;
+
+ currentAzimuthTime = DateTime.Now;
+ }
+ return _azAngle;
+ }
+
+ public void SetElevationAngle(double elAngle)
+ {
+ _elAngle = elAngle;
+ }
+
+ public void SetAzimuthAngle(double azAngle)
+ {
+ _azAngle = azAngle;
+ }
+
+ public bool getUpOrDown()
+ {
+ return upOrDown;
+ }
+
+ public bool getLeftOrRight()
+ {
+ return leftOrRight;
+ }
+
+
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/Sensors/FakeTempSensor.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/Sensors/FakeTempSensor.cs
deleted file mode 100644
index 3c476067..00000000
--- a/ControlRoomApplication/ControlRoomApplication/Controllers/Sensors/FakeTempSensor.cs
+++ /dev/null
@@ -1,97 +0,0 @@
-using ControlRoomApplication.Controllers.Sensors;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace ControlRoomApplication.Simulators.Hardware
-{
- ///
- /// Class for the simulated temperature sensor
- ///
- ///
- public class FakeTempSensor : AbstractTemperatureSensor
- {
-
- double _elTemperature;
- double _azTemperature;
- int _elTempDemoIndex = 0;
- int _azTempDemoIndex = 0;
-
- ///
- /// Simulates getting the elevation temperature
- ///
- ///
- public override double GetElevationTemperature()
- {
- return ReadElevationTempDemo(); //Iterates through an array to
- //simulate reading the temperature like the
- //real device will do
- }
-
- ///
- /// Simulates getting the azimuth temperature
- ///
- ///
- public override double GetAzimuthTemperature()
- {
- return ReadAzimuthTempDemo();
- }
-
- public void SetElevationTemp(double elTemp)
- {
- _elTemperature = elTemp;
- }
-
- public void SetAzimuthTemp(double azTemp)
- {
- _azTemperature = azTemp;
- }
-
- public double ReadElevationTempDemo()
- {
- _elTempDemoIndex++;
-
- double[] elevationTemp = { 74.2, 82.3, 105.4, 89.5, 80.6, 83.7, 100.2, 87.4, 76.6, 105.1, 99.3, 89.9, 75.3, 77.4, 76.7, 89.3, 102.2, 88.7, 88.4, 71.3, 81.2, 78.3, 103.9, 105.4, 102.1, 104.2, 81.5, 70.6, 84.7, 87.5, 101.2, 71.3, 101.6, 90.2, 79.3, 77.4, 99.5, 92.3, 86.1, 97.9, 76.2, 97.8, 95.3, 102.7, 83.4, 103.6, 91.5, 86.3, 70.6, 95.9, 102.2, 100.4, 92.6, 96.8, 100.1, 92.3, 96.5, 81.7, 91.9, 101.8, 95.6, 102.4, 81.2, 78.1, 97.5, 92.3, 88.6, 80.3, 88.8, 105.2, 90.7, 72.5, 78.3, 95.2, 82.4, 85.7, 105.2, 95.6, 95.2, 93.6 };
-
- if (_elTempDemoIndex >= elevationTemp.Length)
- {
- _elTempDemoIndex = 0;
- }
-
- if (_elTempDemoIndex >= 0)
- {
- return elevationTemp[_elTempDemoIndex];
- }
- else
- {
- return 0;
- }
-
- }
-
- public double ReadAzimuthTempDemo()
- {
- _azTempDemoIndex++;
-
- double[] azimuthTemp = { 91, 76, 89, 80 ,70, 85 ,82, 86 ,74 ,96 ,104 ,82, 86 ,101 ,78 ,86, 87, 75 ,98 ,72 ,105 ,92 ,88, 89 ,103 ,72, 91, 83 ,85 ,96 ,89, 72 ,105, 90, 95, 94 ,71 ,99 ,99 ,74 ,98 ,90 ,100 ,83, 73 ,97 ,81 ,73 ,98, 84 ,88 ,85 ,78 ,105 ,78 ,74 ,71 ,79 ,90, 98, 73, 73, 78, 90, 100, 98, 95, 103, 97, 82, 72,93 ,77 ,86 ,101, 81, 81, 74,75, 97 };
-
- if (_azTempDemoIndex >= azimuthTemp.Length)
- {
- _azTempDemoIndex = 0;
- }
-
- if (_azTempDemoIndex >= 0)
- {
- return azimuthTemp[_azTempDemoIndex];
- }
- else
- {
- return 0;
- }
- }
-
- /******END*******/
- }
-}
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/Sensors/LimitSwitchData.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/Sensors/LimitSwitchData.cs
new file mode 100644
index 00000000..0e47f321
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/Sensors/LimitSwitchData.cs
@@ -0,0 +1,30 @@
+using ControlRoomApplication.Controllers.Sensors;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using ControlRoomApplication.Constants;
+
+namespace ControlRoomApplication.Simulators.Hardware
+{
+ ///
+ /// A public struct to store the data regarding the limit switches
+ /// for both the Azimuth and Elevation, for use in the Diagnostics page
+ /// and potentially more
+ ///
+ public struct LimitSwitchData
+ {
+ ///
+ /// limit at 360 degrees
+ ///
+ public bool Azimuth_CW_Limit;
+ ///
+ /// limit at - 10 degrees
+ ///
+ public bool Azimuth_CCW_Limit;
+ public bool Elevation_Lower_Limit;
+ public bool Elevation_Upper_Limit;
+ }
+
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/Sensors/MiscPlcInput.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/Sensors/MiscPlcInput.cs
new file mode 100644
index 00000000..9e164345
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/Sensors/MiscPlcInput.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ControlRoomApplication.Controllers.Sensors {
+ public struct MiscPlcInput {
+ public bool Gate_Sensor;
+ public bool Estop;
+ ///
+ /// the PLC and MCU are both connected to this sensor when it goes high the MCU will capture its current position this will let us track if the triangle connector has slipped on the axsis
+ ///
+ public bool EL_Slip_CAPTURE;
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/Sensors/OverrideSwitchData.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/Sensors/OverrideSwitchData.cs
new file mode 100644
index 00000000..e5ed388e
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/Sensors/OverrideSwitchData.cs
@@ -0,0 +1,130 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using ControlRoomApplication.Controllers.Sensors;
+using ControlRoomApplication.Database;
+using ControlRoomApplication.Entities;
+
+namespace ControlRoomApplication.Controllers.Sensors
+{
+ ///
+ /// A public class to store the override switch data for
+ /// use on DiagnosticsForm.cs and AbstractPLCDriver.cs
+ /// This DOES NOT include weather station sensors.
+ ///
+ public class OverrideSwitchData
+ {
+ // Uses PLC
+ public bool overrideGate { get; set; }
+ public bool overrideElevatProx0 { get; set; }
+ public bool overrideElevatProx90 { get; set; }
+
+ // No longer used
+ public bool overrideAzimuthProx0 { get; set; }
+ public bool overrideAzimuthProx375 { get; set; }
+
+ // Sensor Network
+ public bool overrideAzimuthMotTemp { get; set; }
+ public bool overrideElevatMotTemp { get; set; }
+
+ public bool overrideAzimuthAbsEncoder { get; set; }
+ public bool overrideElevationAbsEncoder { get; set; }
+ public bool overrideAzimuthAccelerometer { get; set; }
+ public bool overrideElevationAccelerometer { get; set; }
+ public bool overrideCounterbalanceAccelerometer { get; set; }
+
+
+ // Parent so we can set PLC values
+ private RadioTelescope RadioTelescope { get; }
+
+ public OverrideSwitchData(RadioTelescope radioTelescope)
+ {
+ RadioTelescope = radioTelescope;
+
+ // PLC
+ overrideGate = DatabaseOperations.GetOverrideStatusForSensor(SensorItemEnum.GATE);
+ overrideElevatProx0 = DatabaseOperations.GetOverrideStatusForSensor(SensorItemEnum.EL_PROXIMITY_0);
+ overrideElevatProx90 = DatabaseOperations.GetOverrideStatusForSensor(SensorItemEnum.EL_PROXIMITY_90);
+
+ // Sensor Network
+ overrideAzimuthMotTemp = DatabaseOperations.GetOverrideStatusForSensor(SensorItemEnum.AZIMUTH_MOTOR);
+ overrideElevatMotTemp = DatabaseOperations.GetOverrideStatusForSensor(SensorItemEnum.ELEVATION_MOTOR);
+
+ overrideAzimuthAbsEncoder = DatabaseOperations.GetOverrideStatusForSensor(SensorItemEnum.AZIMUTH_ABS_ENCODER);
+ overrideElevationAbsEncoder = DatabaseOperations.GetOverrideStatusForSensor(SensorItemEnum.ELEVATION_ABS_ENCODER);
+ overrideAzimuthAccelerometer = DatabaseOperations.GetOverrideStatusForSensor(SensorItemEnum.AZ_MOTOR_VIBRATION);
+ overrideElevationAccelerometer = DatabaseOperations.GetOverrideStatusForSensor(SensorItemEnum.ELEV_MOTOR_VIBRATION);
+ overrideCounterbalanceAccelerometer = DatabaseOperations.GetOverrideStatusForSensor(SensorItemEnum.COUNTER_BALANCE_VIBRATION);
+
+
+ // Azimuth overrides are no longer needed because we are using the slip ring
+ overrideAzimuthProx0 = true;
+ overrideAzimuthProx375 = true;
+ }
+
+ // PLC
+ public void setGatesOverride(bool doOverride)
+ {
+ overrideGate = doOverride;
+ RadioTelescope.PLCDriver.setregvalue((ushort)PLC_modbus_server_register_mapping.GATE_OVERRIDE, Convert.ToUInt16(doOverride));
+ DatabaseOperations.SetOverrideForSensor(SensorItemEnum.GATE, doOverride);
+ }
+
+ public void setElProx0Override(bool doOverride)
+ {
+ overrideElevatProx0 = doOverride;
+ DatabaseOperations.SetOverrideForSensor(SensorItemEnum.EL_PROXIMITY_0, doOverride);
+ }
+
+ public void setElProx90Override(bool doOverride)
+ {
+ overrideElevatProx90 = doOverride;
+ DatabaseOperations.SetOverrideForSensor(SensorItemEnum.EL_PROXIMITY_90, doOverride);
+ }
+
+ // Sensor Network
+ public void setAzimuthMotTemp(bool doOverride)
+ {
+ overrideAzimuthMotTemp = doOverride;
+ DatabaseOperations.SetOverrideForSensor(SensorItemEnum.AZIMUTH_MOTOR, doOverride);
+ }
+
+ public void setElevationMotTemp(bool doOverride)
+ {
+ overrideElevatMotTemp = doOverride;
+ DatabaseOperations.SetOverrideForSensor(SensorItemEnum.ELEVATION_MOTOR, doOverride);
+ }
+
+ public void setAzimuthAbsEncoder(bool doOverride)
+ {
+ overrideAzimuthAbsEncoder = doOverride;
+ DatabaseOperations.SetOverrideForSensor(SensorItemEnum.AZIMUTH_ABS_ENCODER, doOverride);
+ }
+
+ public void setElevationAbsEncoder(bool doOverride)
+ {
+ overrideElevationAbsEncoder = doOverride;
+ DatabaseOperations.SetOverrideForSensor(SensorItemEnum.ELEVATION_ABS_ENCODER, doOverride);
+ }
+
+ public void setAzimuthAccelerometer(bool doOverride)
+ {
+ overrideAzimuthAccelerometer = doOverride;
+ DatabaseOperations.SetOverrideForSensor(SensorItemEnum.AZ_MOTOR_VIBRATION, doOverride);
+ }
+
+ public void setElevationAccelerometer(bool doOverride)
+ {
+ overrideElevationAccelerometer = doOverride;
+ DatabaseOperations.SetOverrideForSensor(SensorItemEnum.ELEV_MOTOR_VIBRATION, doOverride);
+ }
+
+ public void setCounterbalanceAccelerometer(bool doOverride)
+ {
+ overrideCounterbalanceAccelerometer = doOverride;
+ DatabaseOperations.SetOverrideForSensor(SensorItemEnum.COUNTER_BALANCE_VIBRATION, doOverride);
+ }
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/Sensors/ProximitySensorData.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/Sensors/ProximitySensorData.cs
new file mode 100644
index 00000000..81fef69a
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/Sensors/ProximitySensorData.cs
@@ -0,0 +1,17 @@
+using ControlRoomApplication.Controllers.Sensors;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using ControlRoomApplication.Constants;
+
+namespace ControlRoomApplication.Simulators.Hardware
+{
+ public struct HomeSensorData
+ {
+ public bool Azimuth_Home_One;
+ public bool Azimuth_Home_Two;
+ public bool Elevation_Home;
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/Sensors/TempSensorData.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/Sensors/TempSensorData.cs
new file mode 100644
index 00000000..6aec0866
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/Sensors/TempSensorData.cs
@@ -0,0 +1,34 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ControlRoomApplication.Controllers.Sensors
+{
+ ///
+ /// A public struct to store the data from the temperature sensor
+ /// for use in the diagnostics page
+ ///
+ ///
+ public struct TempSensorData
+ {
+ public long azimuthTempTime;
+ public double azimuthTemp;
+
+ public long elevationTempTime;
+ public double elevationTemp;
+
+ public long azimuthAccTime;
+ public double azimuthAcc;
+ public double azimuthX;
+ public double azimuthY;
+ public double azimuthZ;
+
+ public long elevationAccTime;
+ public double elevationAcc;
+ public double elevationX;
+ public double elevationY;
+ public double elevationZ;
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/SpectraCyberControllers/AbstractSpectraCyberController.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/SpectraCyberControllers/AbstractSpectraCyberController.cs
index 839a5ea8..c1b13bed 100644
--- a/ControlRoomApplication/ControlRoomApplication/Controllers/SpectraCyberControllers/AbstractSpectraCyberController.cs
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/SpectraCyberControllers/AbstractSpectraCyberController.cs
@@ -3,6 +3,7 @@
using ControlRoomApplication.Entities;
using ControlRoomApplication.Constants;
using ControlRoomApplication.Database;
+using ControlRoomApplication.Util;
namespace ControlRoomApplication.Controllers
{
@@ -13,7 +14,8 @@ public abstract class AbstractSpectraCyberController : HeartbeatInterface
protected RadioTelescope Parent { get; set; }
protected AbstractSpectraCyber SpectraCyber { get; set; }
- protected SpectraCyberScanSchedule Schedule { get; set; }
+ public SpectraCyberScanSchedule Schedule { get; set; }
+ public SpectraCyberConfigValues configVals;
protected Thread CommunicationThread { get; set; }
protected bool KillCommunicationThreadFlag { get; set; }
@@ -26,8 +28,42 @@ public AbstractSpectraCyberController(AbstractSpectraCyber spectraCyber) : base(
KillCommunicationThreadFlag = false;
CommunicationMutex = new Mutex();
SpectraCyber.CurrentModeType = SpectraCyberModeTypeEnum.CONTINUUM;
+ configVals = new SpectraCyberConfigValues(SpectraCyberModeTypeEnum.CONTINUUM, 0, 0.3,
+ SpectraCyberDCGainEnum.X1, SpectraCyberDCGainEnum.X1, 10, SpectraCyberBandwidthEnum.SMALL_BANDWIDTH, 1200, 0, 0, -600);
}
+ public struct SpectraCyberConfigValues
+ {
+ public SpectraCyberModeTypeEnum spectraCyberMode;
+ public double offsetVoltage;
+ public double integrationStep;
+ public double IFGain;
+ public SpectraCyberDCGainEnum specGain;
+ public SpectraCyberDCGainEnum contGain;
+ public SpectraCyberBandwidthEnum bandwidth;
+ public double frequency;
+ public double rfData;
+ public double scanTime;
+ public double bandscan;
+
+ public SpectraCyberConfigValues(SpectraCyberModeTypeEnum spectraCyberModeIN, double offsetVoltageIN, double integrationStepIN,
+ SpectraCyberDCGainEnum specGainIN, SpectraCyberDCGainEnum contGainIN,
+ double IFGainIN, SpectraCyberBandwidthEnum bandwidthIN, double frequencyIN, double rfDataIN, double scanTimeIN, double bandscanIn)
+ {
+ spectraCyberMode = spectraCyberModeIN;
+ offsetVoltage = offsetVoltageIN;
+ integrationStep = integrationStepIN;
+ IFGain = IFGainIN;
+ specGain = specGainIN;
+ contGain = contGainIN;
+ bandwidth = bandwidthIN;
+ frequency = frequencyIN;
+ rfData = rfDataIN;
+ scanTime = scanTimeIN;
+ bandscan = bandscanIn;
+ }
+ };
+
public RadioTelescope GetParent()
{
return Parent;
@@ -41,41 +77,132 @@ public void SetParent(RadioTelescope rt)
public bool SetApptConfig(Appointment appt)
{
bool success = false;
- SetActiveAppointmentID(appt.Id);
+ SetActiveAppointment(appt);
SpectraCyberConfig config = appt.SpectraCyberConfig;
- SetSpectraCyberModeType(config.Mode);
- if(config.Mode == SpectraCyberModeTypeEnum.CONTINUUM)
+ SetSpectraCyberModeType(config._Mode);
+ if(config._Mode == SpectraCyberModeTypeEnum.CONTINUUM)
{
success = SetContinuumIntegrationTime(config.IntegrationTime) && SetContinuumOffsetVoltage(config.OffsetVoltage);
}
- else if(config.Mode == SpectraCyberModeTypeEnum.SPECTRAL)
+ else if(config._Mode == SpectraCyberModeTypeEnum.SPECTRAL)
{
success = SetSpectralOffsetVoltage(config.OffsetVoltage) && SetSpectralIntegrationTime(config.IntegrationTime);
}
else
{
// Unknown current mode type
- logger.Info("[AbstractSpectraCyberController] ERROR: invalid SpectraCyber mode type: " + SpectraCyber.CurrentModeType.ToString());
+ logger.Info(Utilities.GetTimeStamp() + ": [AbstractSpectraCyberController] ERROR: invalid SpectraCyber mode type: " + SpectraCyber.CurrentModeType.ToString());
}
return success;
}
+ public bool SetSpectraCyberIFGain(double ifGain)
+ {
+ if(ifGain < 10.0 || ifGain > 25.75)
+ {
+ logger.Info(Utilities.GetTimeStamp() + ": [AbstractSpectraCyberController] ERROR: invalid IF Gain value: " + ifGain);
+ return false;
+ }
+
+ double adjustedGain = (ifGain - 10.0) / 0.25;
+
+ string Command = "!A" + IntToHexString(Convert.ToInt32(adjustedGain));
+
+ SpectraCyberRequest Request = new SpectraCyberRequest(
+ SpectraCyberCommandTypeEnum.CHANGE_SETTING,
+ Command,
+ false,
+ 4
+ );
+
+ SpectraCyberResponse Response = new SpectraCyberResponse();
+ SendCommand(Request, ref Response);
+
+ configVals.IFGain = ifGain;
+
+ return Response.RequestSuccessful;
+ }
+
+ public bool SetSpectraCyberDCGain(int dcgain, string identifier)
+ {
+ string Command = "!" + identifier + IntToHexString(dcgain);
+
+ SpectraCyberRequest Request = new SpectraCyberRequest(
+ SpectraCyberCommandTypeEnum.CHANGE_SETTING,
+ Command,
+ false,
+ 4
+ );
+
+ SpectraCyberResponse Response = new SpectraCyberResponse();
+ SendCommand(Request, ref Response);
+
+ return Response.RequestSuccessful;
+ }
+
+ public bool SetSpecGain(SpectraCyberDCGainEnum specGain)
+ {
+ // Spec Gain is K00X where x is the enum
+ int gain = 0;
+
+ if (specGain == SpectraCyberDCGainEnum.X1)
+ gain = 0;
+ else if (specGain == SpectraCyberDCGainEnum.X5)
+ gain = 1;
+ else if (specGain == SpectraCyberDCGainEnum.X10)
+ gain = 2;
+ else if (specGain == SpectraCyberDCGainEnum.X20)
+ gain = 3;
+ else if (specGain == SpectraCyberDCGainEnum.X50)
+ gain = 4;
+ else if (specGain == SpectraCyberDCGainEnum.X60)
+ gain = 5;
+
+ configVals.specGain = specGain;
+
+ return SetSpectraCyberDCGain(gain, "K");
+ }
+
+ public bool SetContGain(SpectraCyberDCGainEnum contGain)
+ {
+ // Spec Gain is K00X where x is the enum
+ int gain = 0;
+
+ if (contGain == SpectraCyberDCGainEnum.X1)
+ gain = 0;
+ else if (contGain == SpectraCyberDCGainEnum.X5)
+ gain = 1;
+ else if (contGain == SpectraCyberDCGainEnum.X10)
+ gain = 2;
+ else if (contGain == SpectraCyberDCGainEnum.X20)
+ gain = 3;
+ else if (contGain == SpectraCyberDCGainEnum.X50)
+ gain = 4;
+ else if (contGain == SpectraCyberDCGainEnum.X60)
+ gain = 5;
+
+ configVals.specGain = contGain;
+
+ return SetSpectraCyberDCGain(gain, "G");
+ }
+
public void SetSpectraCyberModeType(SpectraCyberModeTypeEnum type)
{
+ configVals.spectraCyberMode = type;
SpectraCyber.CurrentModeType = type;
}
- public void SetActiveAppointmentID(int apptId)
+ public void SetActiveAppointment(Appointment appt)
{
CommunicationMutex.WaitOne();
- SpectraCyber.ActiveAppointmentID = apptId;
+ SpectraCyber.ActiveAppointment = appt;
CommunicationMutex.ReleaseMutex();
}
public void RemoveActiveAppointmentID()
{
- SetActiveAppointmentID(-1);
+ SetActiveAppointment(null);
}
public void TestCommunication()
@@ -91,17 +218,19 @@ public void TestCommunication()
SendCommand(Request, ref Response);
string ResponseData = Response.SerialIdentifier + Response.DecimalData.ToString("X3");
- logger.Info("[AbstractSpectraCyberController] Attempted RESET with command \"!R000\", heard back: " + ResponseData);
+ logger.Info(Utilities.GetTimeStamp() + ": [AbstractSpectraCyberController] Attempted RESET with command \"!R000\", heard back: " + ResponseData);
}
private bool SetSomeOffsetVoltage(double offset, char identifier)
{
if ((offset < 0.0) || (offset > 4.095))
{
- logger.Info("[AbstractSpectraCyberController] ERROR: input voltage outside of range [0, 4.095]");
+ logger.Info(Utilities.GetTimeStamp() + ": [AbstractSpectraCyberController] ERROR: input voltage outside of range [0, 4.095]");
return false;
}
+ configVals.offsetVoltage = offset;
+
int Magnitude = (int)(offset * 1000);
string Command = "!" + identifier + IntToHexString(Magnitude);
@@ -147,16 +276,99 @@ private bool SetSomeIntegrationTime(SpectraCyberIntegrationTimeEnum time, char i
public bool SetContinuumIntegrationTime(SpectraCyberIntegrationTimeEnum time)
{
+ if (time == SpectraCyberIntegrationTimeEnum.SHORT_TIME_SPAN)
+ {
+ configVals.integrationStep = 0.3;
+ Schedule.ScanDelayMS = 300;
+ }
+ else if (time == SpectraCyberIntegrationTimeEnum.MID_TIME_SPAN)
+ {
+ configVals.integrationStep = 1.0;
+ Schedule.ScanDelayMS = 1000;
+ }
+ else if (time == SpectraCyberIntegrationTimeEnum.LONG_TIME_SPAN)
+ {
+ configVals.integrationStep = 10.0;
+ Schedule.ScanDelayMS = 10000;
+ }
return SetSomeIntegrationTime(time, 'I');
}
public bool SetSpectralIntegrationTime(SpectraCyberIntegrationTimeEnum time)
{
+ if (time == SpectraCyberIntegrationTimeEnum.SHORT_TIME_SPAN)
+ {
+ configVals.integrationStep = 0.3;
+ Schedule.ScanDelayMS = 300;
+ }
+ else if (time == SpectraCyberIntegrationTimeEnum.MID_TIME_SPAN)
+ {
+ configVals.integrationStep = 0.5;
+ Schedule.ScanDelayMS = 500;
+ }
+ else if (time == SpectraCyberIntegrationTimeEnum.LONG_TIME_SPAN)
+ {
+ configVals.integrationStep = 1.0;
+ Schedule.ScanDelayMS = 1000;
+ }
return SetSomeIntegrationTime(time, 'L');
}
+ public bool SetFrequency(double frequency)
+ {
+ string Command = "!F" + IntToHexString(Convert.ToInt32(frequency));
+
+ SpectraCyberRequest Request = new SpectraCyberRequest(
+ SpectraCyberCommandTypeEnum.CHANGE_SETTING,
+ Command,
+ false,
+ 4
+ );
+
+ SpectraCyberResponse Response = new SpectraCyberResponse();
+ SendCommand(Request, ref Response);
+
+ configVals.frequency = frequency;
+ configVals.bandscan = -1 * (configVals.frequency / 2);
+
+ return Response.RequestSuccessful;
+ }
+
+ public bool SetBandwidth(SpectraCyberBandwidthEnum bandwidth)
+ {
+ // Our spectra cyber does not use this command
+ /*
+ string Command = "";
+
+ if (bandwidth.GetValue().Equals("15Khz"))
+ {
+ Command = "!B000";
+
+ }
+ else if (bandwidth.GetValue().Equals("30Khz"))
+ {
+ Command = "!B001";
+ }
+
+ SpectraCyberRequest Request = new SpectraCyberRequest(
+ SpectraCyberCommandTypeEnum.CHANGE_SETTING,
+ Command,
+ false,
+ 4
+ );
+
+ SpectraCyberResponse Response = new SpectraCyberResponse();
+ SendCommand(Request, ref Response);
+
+ configVals.bandwidth = bandwidth;
+
+ return Response.RequestSuccessful;
+ */
+ return true;
+ }
+
// Perform a single scan, based on current mode
- protected SpectraCyberResponse DoSpectraCyberScan()
+ public SpectraCyberResponse DoSpectraCyberScan()
{
SpectraCyberResponse Response = new SpectraCyberResponse();
@@ -183,8 +395,13 @@ public void SingleScan()
}
// Start scanning, keep doing so until requested to stop
- public void StartScan()
+ public void StartScan(Appointment appt)
{
+
+ // set the spectra cyber active appointment so that rf data has an appointment to refer to
+ SpectraCyber.ActiveAppointment = appt;
+
+ logger.Info(Utilities.GetTimeStamp() + ": [SpectraCyberAbstractController] Scan has been started");
try
{
CommunicationMutex.WaitOne();
@@ -200,10 +417,14 @@ public void StartScan()
// Stop scanning and return scan results
public void StopScan()
{
+ logger.Info(Utilities.GetTimeStamp() + ": [SpectraCyberAbstractController] Scan has been stopped");
+
try
{
CommunicationMutex.WaitOne();
Schedule.SetModeOff();
+ configVals.scanTime = 0;
+ configVals.bandscan = -1 * (configVals.frequency / 2);
CommunicationMutex.ReleaseMutex();
}
catch
@@ -264,6 +485,8 @@ public void RunCommunicationThread()
{
bool KeepRunningCommsThread = true;
+ logger.Info(Utilities.GetTimeStamp() + ": [SpectraCyberController] The scan schedule type is " + Schedule.GetMode());
+
// Loop until the thread is attempting to be shutdown (don't directly reference SpectraCyber.KillCommunicationThreadFlag
// because it can't be kept in the mutex's scope)
while (KeepRunningCommsThread)
@@ -273,9 +496,8 @@ public void RunCommunicationThread()
if (Schedule.PollReadiness())
{
- AddToRFDataDatabase(DoSpectraCyberScan(), SpectraCyber.ActiveAppointmentID);
+ AddToRFDataDatabase(DoSpectraCyberScan(), SpectraCyber.ActiveAppointment);
Schedule.Consume();
- //logger.Info("[AbstractSpectraCyberController] SC Scan");
}
// Tell the loop to break on its next pass (so the mutex is still released if the flag is high)
@@ -289,11 +511,8 @@ public void RunCommunicationThread()
// Implicitly kills the processing thread and waits for it to join before returning
public void KillCommunicationThreadAndWait()
{
- CommunicationMutex.WaitOne();
KillCommunicationThreadFlag = true;
- CommunicationMutex.ReleaseMutex();
-
- CommunicationThread.Join();
+ if(CommunicationThread.IsAlive) CommunicationThread.Join();
}
protected override bool KillHeartbeatComponent()
@@ -301,14 +520,25 @@ protected override bool KillHeartbeatComponent()
return BringDown();
}
- private RFData AddToRFDataDatabase(SpectraCyberResponse spectraCyberResponse, int appId)
+ private RFData AddToRFDataDatabase(SpectraCyberResponse spectraCyberResponse, Appointment appt)
{
RFData rfData = RFData.GenerateFrom(spectraCyberResponse);
+ appt = DatabaseOperations.GetUpdatedAppointment(appt);
+ rfData.Appointment = appt;
+ rfData.Intensity = rfData.Intensity * MiscellaneousHardwareConstants.SPECTRACYBER_VOLTS_PER_STEP;
- //
// Add to database
- //
- DatabaseOperations.CreateRFData(appId, rfData);
+ DatabaseOperations.AddRFData(rfData);
+
+ configVals.rfData = rfData.Intensity;
+
+ if (configVals.spectraCyberMode == SpectraCyberModeTypeEnum.SPECTRAL)
+ if (configVals.bandscan > configVals.frequency / 2)
+ configVals.bandscan = -1 * (configVals.frequency / 2);
+ else
+ configVals.bandscan = configVals.bandscan + MiscellaneousHardwareConstants.SPECTRACYBER_BANDWIDTH_STEP;
+ else if (configVals.spectraCyberMode == SpectraCyberModeTypeEnum.CONTINUUM)
+ configVals.scanTime = configVals.scanTime + configVals.integrationStep;
return rfData;
}
@@ -317,7 +547,6 @@ private RFData AddToRFDataDatabase(SpectraCyberResponse spectraCyberResponse, in
public abstract bool BringDown();
protected abstract void SendCommand(SpectraCyberRequest request, ref SpectraCyberResponse response);
- // TODO: implement proper error handling if ch is out of acceptable range
protected static int HexCharToInt(char ch)
{
int baseVal = Convert.ToByte(ch);
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/SpectraCyberControllers/SpectraCyberController.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/SpectraCyberControllers/SpectraCyberController.cs
index 06aeea4f..8780d49b 100644
--- a/ControlRoomApplication/ControlRoomApplication/Controllers/SpectraCyberControllers/SpectraCyberController.cs
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/SpectraCyberControllers/SpectraCyberController.cs
@@ -3,6 +3,8 @@
using System.Threading;
using ControlRoomApplication.Entities;
using ControlRoomApplication.Constants;
+using ControlRoomApplication.Util;
+
namespace ControlRoomApplication.Controllers
{
@@ -30,12 +32,14 @@ public override bool BringUp()
ReadTimeout = AbstractSpectraCyberConstants.TIMEOUT_MS,
WriteTimeout = AbstractSpectraCyberConstants.TIMEOUT_MS
};
+
+ logger.Info(Utilities.GetTimeStamp() + ": [SpectraCyberController] Created serial port connection");
}
catch (Exception e)
{
if (e is System.IO.IOException)
{
- logger.Info("[SpectraCyberController] Failed creating serial port connection.");
+ logger.Info(Utilities.GetTimeStamp() + ": [SpectraCyberController] Failed creating serial port connection.");
return false;
}
else
@@ -48,6 +52,8 @@ public override bool BringUp()
try
{
((SpectraCyber)SpectraCyber).SerialPort.Open();
+
+ logger.Info(Utilities.GetTimeStamp() + ": [SpectraCyberController] Serial port has been opened");
}
catch (Exception e)
{
@@ -57,7 +63,7 @@ public override bool BringUp()
|| e is ArgumentException
|| e is UnauthorizedAccessException)
{
- logger.Info("[SpectraCyberController] Failed opening serial communication.");
+ logger.Info(Utilities.GetTimeStamp() + ": [SpectraCyberController] Failed opening serial communication.");
return false;
}
else
@@ -71,18 +77,21 @@ public override bool BringUp()
{
// Initialize thread and start it
CommunicationThread = new Thread(() => RunCommunicationThread());
+ logger.Info(Utilities.GetTimeStamp() + ": [SpectraCyberController] The communication thread has been assigned");
+
CommunicationThread.Start();
+ logger.Info(Utilities.GetTimeStamp() + ": [SpectraCyberController] The communication thread has started");
}
catch (Exception e)
{
if (e is ArgumentNullException)
{
- logger.Info("[SpectraCyberController] Failed creating communication thread.");
+ logger.Info(Utilities.GetTimeStamp() + ": [SpectraCyberController] Failed creating communication thread.");
return false;
}
else if (e is ThreadStartException || e is OutOfMemoryException)
{
- logger.Info("[SpectraCyberController] Failed starting communication thread.");
+ logger.Info(Utilities.GetTimeStamp() + ": [SpectraCyberController] Failed starting communication thread.");
return false;
}
else
@@ -92,7 +101,7 @@ public override bool BringUp()
}
}
- logger.Info("[SpectraCyberController] Successfully started SpectraCyber communication and communication thread.");
+ logger.Info(Utilities.GetTimeStamp() + ": [SpectraCyberController] Successfully started SpectraCyber communication and communication thread.");
return true;
}
@@ -104,6 +113,8 @@ public override bool BringDown()
{
((SpectraCyber)SpectraCyber).SerialPort.Close();
}
+
+ logger.Info(Utilities.GetTimeStamp() + ": [SpectraCyberController] The serial port has been closed");
}
catch (Exception e)
{
@@ -120,7 +131,7 @@ public override bool BringDown()
KillCommunicationThreadAndWait();
- logger.Info("[SpectraCyberController] Successfully killed SpectraCyber communication and communication thread.");
+ logger.Info(Utilities.GetTimeStamp() + ": [SpectraCyberController] Successfully killed SpectraCyber communication and communication thread.");
return true;
}
@@ -159,7 +170,7 @@ protected override void SendCommand(SpectraCyberRequest request, ref SpectraCybe
BringDown();
break;
- // TODO: implement this case further probably
+ // This command type is unused
case SpectraCyberCommandTypeEnum.SCAN_STOP:
break;
@@ -236,7 +247,7 @@ protected override void SendCommand(SpectraCyberRequest request, ref SpectraCybe
catch (Exception e)
{
// Something went wrong, the response isn't valid
- logger.Info("[SpectraCyberController] Failed to receive a response: " + e.ToString());
+ logger.Info(Utilities.GetTimeStamp() + ": [SpectraCyberController] Failed to receive a response: " + e.ToString());
response.Valid = false;
}
}
@@ -246,7 +257,7 @@ protected override void SendCommand(SpectraCyberRequest request, ref SpectraCybe
}
// Test if the physical SpectraCyber is alive, while making sure to not interrupt the schedule
- protected override bool TestIfComponentIsAlive()
+ public override bool TestIfComponentIsAlive()
{
// If the SpectraCyber has already told us it failed, then it's clearly not alive
if (SerialCommsFailed)
@@ -294,7 +305,7 @@ protected override bool TestIfComponentIsAlive()
}
else
{
- logger.Info("[SpectraCyberController] Unpredicted scheduling combination...");
+ logger.Info(Utilities.GetTimeStamp() + ": [SpectraCyberController] Unpredicted scheduling combination...");
return true;
}
}
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/SpectraCyberControllers/SpectraCyberSimulatorController.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/SpectraCyberControllers/SpectraCyberSimulatorController.cs
index 2bfcd833..f254ed32 100644
--- a/ControlRoomApplication/ControlRoomApplication/Controllers/SpectraCyberControllers/SpectraCyberSimulatorController.cs
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/SpectraCyberControllers/SpectraCyberSimulatorController.cs
@@ -2,6 +2,8 @@
using System.Threading;
using ControlRoomApplication.Entities;
using ControlRoomApplication.Constants;
+using ControlRoomApplication.Util;
+
namespace ControlRoomApplication.Controllers
{
@@ -29,12 +31,12 @@ public override bool BringUp()
{
if (e is ArgumentNullException)
{
- logger.Info("[SpectraCyberSimulatorController] Failed creating communication thread.");
+ logger.Info(Utilities.GetTimeStamp() + ": [SpectraCyberSimulatorController] Failed creating communication thread.");
return false;
}
else if (e is ThreadStartException || e is OutOfMemoryException)
{
- logger.Info("[SpectraCyberSimulatorController] Failed starting communication thread.");
+ logger.Info(Utilities.GetTimeStamp() + ": [SpectraCyberSimulatorController] Failed starting communication thread.");
return false;
}
else
@@ -44,7 +46,7 @@ public override bool BringUp()
}
}
- logger.Info("[SpectraCyberSimulatorController] Successfully started SpectraCyber communication and communication thread.");
+ logger.Info(Utilities.GetTimeStamp() + ": [SpectraCyberSimulatorController] Successfully started SpectraCyber communication and communication thread.");
return true;
}
@@ -52,7 +54,7 @@ public override bool BringDown()
{
KillCommunicationThreadAndWait();
- logger.Info("[SpectraCyberSimulatorController] Successfully killed SpectraCyber communication and communication thread.");
+ logger.Info(Utilities.GetTimeStamp() + ": [SpectraCyberSimulatorController] Successfully killed SpectraCyber communication and communication thread.");
return true;
}
@@ -90,6 +92,7 @@ protected override void SendCommand(SpectraCyberRequest request, ref SpectraCybe
response.SerialIdentifier = request.ResponseIdentifier;
// Generate random data
+ // TODO: may need to update to more accurately match the data seen from the real spectra cyber, or use a CSV file (issue #409)
int minIntensityScaled = (int)(AbstractSpectraCyberConstants.SIMULATED_RF_INTENSITY_MINIMUM / AbstractSpectraCyberConstants.SIMULATED_RF_INTENSITY_DISCRETIZATION);
int maxIntensityScaled = (int)(AbstractSpectraCyberConstants.SIMULATED_RF_INTENSITY_MAXIMUM / AbstractSpectraCyberConstants.SIMULATED_RF_INTENSITY_DISCRETIZATION);
response.DecimalData = random.Next(minIntensityScaled, maxIntensityScaled + 1);
@@ -101,9 +104,10 @@ protected override void SendCommand(SpectraCyberRequest request, ref SpectraCybe
// Do nothing to purge a simulated buffer
}
- protected override bool TestIfComponentIsAlive()
+ public override bool TestIfComponentIsAlive()
{
return true;
}
+
}
}
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/Controllers/SpectraCyberControllers/SpectraCyberTestController.cs b/ControlRoomApplication/ControlRoomApplication/Controllers/SpectraCyberControllers/SpectraCyberTestController.cs
index a5046255..7c7c362c 100644
--- a/ControlRoomApplication/ControlRoomApplication/Controllers/SpectraCyberControllers/SpectraCyberTestController.cs
+++ b/ControlRoomApplication/ControlRoomApplication/Controllers/SpectraCyberControllers/SpectraCyberTestController.cs
@@ -19,12 +19,13 @@ public override bool BringUp()
return true;
}
+
protected override void SendCommand(SpectraCyberRequest request, ref SpectraCyberResponse response)
{
// pass
}
- protected override bool TestIfComponentIsAlive()
+ public override bool TestIfComponentIsAlive()
{
//throw new System.NotImplementedException();
return true;
diff --git a/ControlRoomApplication/ControlRoomApplication/Database/Operations/DatabaseOperations.cs b/ControlRoomApplication/ControlRoomApplication/Database/Operations/DatabaseOperations.cs
index d2cf297c..ae91c04f 100644
--- a/ControlRoomApplication/ControlRoomApplication/Database/Operations/DatabaseOperations.cs
+++ b/ControlRoomApplication/ControlRoomApplication/Database/Operations/DatabaseOperations.cs
@@ -1,10 +1,19 @@
using System;
using System.Collections.Generic;
using System.Data.Entity.Infrastructure;
+using System.Data.Entity;
+using System.Data.Entity.Infrastructure;
+using System.Data.Entity.Migrations;
using System.Linq;
using ControlRoomApplication.Constants;
using ControlRoomApplication.Entities;
+using ControlRoomApplication.Controllers;
using ControlRoomApplication.Main;
+using System.Reflection;
+using System.Data.Entity.Core.Objects;
+using ControlRoomApplication.Util;
+using System.Threading;
+using System.Text;
namespace ControlRoomApplication.Database
{
@@ -13,6 +22,11 @@ public static class DatabaseOperations
private static readonly bool USING_REMOTE_DATABASE = false;
private static readonly log4net.ILog logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
+ // used to tell if we need to create a control room user
+ // if control room user is already in the database, we do not want to push any users
+ // if it is not in the database, we want to create one then no more
+ private static bool createUser = false;
+
///
/// Updates the appointment status by saving the appt passed in.
///
@@ -52,170 +66,246 @@ private static RTDbContext InitializeDatabaseContext()
}
else
{
- RTDbContext LocalContext = new RTDbContext();
- LocalContext.Database.CreateIfNotExists();
+ RTDbContext LocalContext = new RTDbContext(AWSConstants.LOCAL_DATABASE_STRING);
SaveContext(LocalContext);
return LocalContext;
}
}
///
- /// Populates the local database with 4 appointments for testing purposes.
+ /// Adds an appointment to the database
///
- public static void PopulateLocalDatabase(int RT_id)
+ public static void AddAppointment(Appointment appt)
{
- if (!USING_REMOTE_DATABASE)
+
+ using (RTDbContext Context = InitializeDatabaseContext())
{
- Random rand = new Random();
+ if (createUser == false)
+ {
+ // we have this line so that we do not add another user
+ Context.Entry(appt.User).State = EntityState.Unchanged;
+ }
+ else
+ {
+ Context.Users.Add(appt.User);
+ createUser = false;
+ }
+
+ if (Context.CelestialBodies.Any(t => t.Id == appt.CelestialBody.Id) == false)
+ {
+ if (Context.Coordinates.Any(t => t.Id == appt.CelestialBody.Coordinate.Id))
+ Context.Entry(appt.CelestialBody.Coordinate).State = EntityState.Unchanged;
+
+ Context.CelestialBodies.Add(appt.CelestialBody);
+ }
+ if (Context.Orientations.Any(t => t.Id == appt.Orientation.Id) == false)
+ Context.Orientations.Add(appt.Orientation);
+ if (Context.SpectraCyberConfigs.Any(t => t.Id == appt.SpectraCyberConfig.Id) == false)
+ Context.SpectraCyberConfigs.Add(appt.SpectraCyberConfig);
+
+ Context.Entry(appt.Telescope).State = EntityState.Unchanged;
+
+ Context.Appointments.Add(appt);
+ SaveContext(Context);
+ // Add coordinates
+ List alist = Context.Appointments.ToList();
+ foreach (Coordinate c in appt.Coordinates)
+ {
+ c.apptId = alist[alist.Count - 1].Id;
+ Context.Coordinates.AddOrUpdate(c);
+ }
+ SaveContext(Context);
+ }
+ }
+
+ //Update telescope to online
+ public static void UpdateTelescope(RadioTelescope radioTelescope)
+ {
+
using (RTDbContext Context = InitializeDatabaseContext())
{
- List appts = new List();
-
- DateTime DateTimeUniversalStart = DateTime.UtcNow.AddMinutes(1);
-
- Appointment appt0 = new Appointment();
- Appointment appt1 = new Appointment();
- Appointment appt2 = new Appointment();
- Appointment appt3 = new Appointment();
-
- Coordinate coordinate0 = new Coordinate();
- Coordinate coordinate1 = new Coordinate();
- Coordinate coordinate2 = new Coordinate();
- Coordinate coordinate3 = new Coordinate();
-
- coordinate0.RightAscension = 10.3;
- coordinate0.Declination = 50.8;
-
- coordinate1.RightAscension = 22.0;
- coordinate1.Declination = 83.63;
-
- coordinate2.RightAscension = 16.0;
- coordinate2.Declination = 71.5;
-
- coordinate3.RightAscension = 26.3;
- coordinate3.Declination = 85.12;
-
- // Add drift scan appointment
- appt0.StartTime = DateTimeUniversalStart.AddSeconds(20 + rand.Next(30));
- appt0.EndTime = appt0.StartTime.AddSeconds(10 + rand.Next(90));
- appt0.Status = AppointmentStatusEnum.REQUESTED;
- appt0.Type = AppointmentTypeEnum.DRIFT_SCAN;
- appt0.Orientation = new Orientation(30, 30);
- appt0.SpectraCyberConfig = new SpectraCyberConfig(SpectraCyberModeTypeEnum.CONTINUUM);
- appt0.TelescopeId = RT_id;
- appt0.UserId = 1;
-
- // Add celesital body appointment
- appt1.StartTime = appt0.EndTime.AddSeconds(20 + rand.Next(30));
- appt1.EndTime = appt1.StartTime.AddSeconds(10 + rand.Next(90));
- appt1.Status = AppointmentStatusEnum.REQUESTED;
- appt1.Type = AppointmentTypeEnum.CELESTIAL_BODY;
- appt1.CelestialBody = new CelestialBody(CelestialBodyConstants.SUN);
- appt1.SpectraCyberConfig = new SpectraCyberConfig(SpectraCyberModeTypeEnum.SPECTRAL);
- appt1.TelescopeId = RT_id;
- appt1.UserId = 1;
-
- // Add point appointment
- appt2.StartTime = appt1.EndTime.AddSeconds(20 + rand.Next(30));
- appt2.EndTime = appt2.StartTime.AddSeconds(10 + rand.Next(90));
- appt2.Status = AppointmentStatusEnum.REQUESTED;
- appt2.Type = AppointmentTypeEnum.POINT;
- appt2.Coordinates.Add(coordinate2);
- appt2.SpectraCyberConfig = new SpectraCyberConfig(SpectraCyberModeTypeEnum.CONTINUUM);
- appt2.TelescopeId = RT_id;
- appt2.UserId = 1;
-
- // Add raster appointment
- appt3.StartTime = appt2.EndTime.AddSeconds(20 + rand.Next(30));
- appt3.EndTime = appt3.StartTime.AddMinutes(10 + rand.Next(90));
- appt3.Status = AppointmentStatusEnum.REQUESTED;
- appt3.Type = AppointmentTypeEnum.RASTER;
- appt3.Coordinates.Add(coordinate0);
- appt3.Coordinates.Add(coordinate1);
- appt3.SpectraCyberConfig = new SpectraCyberConfig(SpectraCyberModeTypeEnum.CONTINUUM);
- appt3.TelescopeId = RT_id;
- appt3.UserId = 1;
-
- appts.AddRange(new Appointment[] { appt0, appt1, appt2, appt3 });
-
- Context.Appointments.AddRange(appts);
+ // Update radio telescope
+
+ radioTelescope.Location.Id = radioTelescope.location_id;
+ Context.Location.AddOrUpdate(radioTelescope.Location);
+
+ radioTelescope.CurrentOrientation.Id = radioTelescope.current_orientation_id;
+ Context.Orientations.AddOrUpdate(radioTelescope.CurrentOrientation);
+
+ radioTelescope.CalibrationOrientation.Id = radioTelescope.calibration_orientation_id;
+ Context.Orientations.AddOrUpdate(radioTelescope.CalibrationOrientation);
+
+ Context.RadioTelescope.AddOrUpdate(radioTelescope);
SaveContext(Context);
+
+ }
+
+
+ }
+
+
+ ///
+ /// Returns the list of Appointments from the database.
+ ///
+ public static List GetListOfAppointmentsForRadioTelescope(int radioTelescopeId)
+ {
+ List appts = new List();
+ using (RTDbContext Context = InitializeDatabaseContext())
+ {
+ try
+ {
+
+ // Use Include method to load related entities from the database
+ var appoints = Context.Appointments.Include(t => t.Telescope)
+ .Include(t => t.CelestialBody)
+ .Include(t => t.CelestialBody.Coordinate)
+ .Include(t => t.Orientation)
+ .Include(t => t.SpectraCyberConfig)
+ .Include(t => t.User)
+ .ToList();
+
+ appts = appoints.Where(x => x.telescope_id == radioTelescopeId).OrderBy(x => x.Id).ToList();
+
+ // Add coordinates to the appointment
+ var coordsForAppt = Context.Coordinates.ToList();
+
+ foreach(Appointment a in appts)
+ {
+ foreach(Coordinate c in coordsForAppt)
+ {
+ if(c.apptId == a.Id) a.Coordinates.Add(c);
+ }
+ }
}
+ catch (Exception e)
+ {
+ ;
+ }
+
}
+ return appts;
}
///
- /// Adds an appointment to the database
+ /// Returns the object of the control room user that we will use for all control room movements
///
- public static void AddAppointment(Appointment appt)
+ public static User GetControlRoomUser()
{
- if (!USING_REMOTE_DATABASE)
+ User controlRoomUser = null;
+ using (RTDbContext Context = InitializeDatabaseContext())
{
- using (RTDbContext Context = InitializeDatabaseContext())
+ // Use Include method to load related entities from the database
+ List users = Context.Users.SqlQuery("Select * from user WHERE first_name = 'control'").ToList();
+
+ // users = users.Where(x => x.first_name == "control").ToList();
+
+ if(users.Count() == 0)
{
- Context.Appointments.Add(appt);
- SaveContext(Context);
+ users.Add(new User("control", "room", "controlroom@gmail.com", NotificationTypeEnum.SMS));
+ createUser = true;
}
+ if(users.Count() > 1)
+ {
+ throw new System.InvalidOperationException("Too many control room users");
+ }
+
+ controlRoomUser = users[0];
}
+ return controlRoomUser;
}
///
- /// Deletes the local database, if it exists.
+ /// Returns a list of all Users
///
- public static void DeleteLocalDatabase()
+ public static List GetAllUsers()
{
- if (!USING_REMOTE_DATABASE)
+ List AllUsers = new List();
+
+ using (RTDbContext Context = InitializeDatabaseContext())
{
- using (RTDbContext Context = InitializeDatabaseContext())
+ AllUsers = Context.Users.SqlQuery("Select * from user").ToList();
+
+ if (AllUsers.Count() == 0)
{
- Context.Database.Delete();
+ AllUsers.Add(new User("control", "room", "controlroom@gmail.com", NotificationTypeEnum.EMAIL));
+
+ Context.Database.ExecuteSqlCommand("INSERT INTO user (first_name, last_name, email_address, notification_type) VALUES ('control', 'room', 'controlroom@gmail.com', 'ALL')");
SaveContext(Context);
}
}
+ return AllUsers;
+ }
+
+ ///
+ /// Returns a list of all Admin Users
+ ///
+ public static List GetAllAdminUsers(bool testflag = false)
+ {
+ List AdminUsers = new List();
+
+ using (RTDbContext Context = InitializeDatabaseContext())
+ {
+ AdminUsers = Context.Users.SqlQuery("SELECT * FROM user U INNER JOIN user_role UR ON U.id = UR.user_id WHERE UR.role = 'ADMIN'").ToList();
+ }
+ if(AdminUsers.Count() == 0 && testflag)
+ {
+ User dummy = CreateDummyUser();
+ AdminUsers.Add(dummy);
+ }
+ // We have to manually add the UserRole object to the admins pulled from the list; it doesn't travel with the SQL query
+ foreach (User u in AdminUsers)
+ {
+ UserRole ur = new UserRole(u.Id, UserRoleEnum.ADMIN);
+ u.UR = ur;
+ }
+ return AdminUsers;
}
///
- /// Returns the list of Appointments from the given context.
+ /// FOR TEST PURPOSES ONLY. Creates a dummy Admin-level user.
///
- private static DbQuery QueryAppointments(RTDbContext Context)
+ /// Returns a fake 'user' with Admin privileges.
+ public static User CreateDummyUser()
{
- // Use Include method to load related entities from the database
- return Context.Appointments.Include("Coordinates")
- .Include("CelestialBody.Coordinate")
- .Include("Orientation")
- .Include("RFDatas")
- .Include("SpectraCyberConfig");
+ User u = new User();
+ using (RTDbContext Context = InitializeDatabaseContext())
+ {
+ AddNewDummyUser();
+ u = GetDummyUser();
+
+ Context.Database.ExecuteSqlCommand($"INSERT INTO user_role SET user_id = '{u.Id}', role = 'ADMIN'");
+ SaveContext(Context);
+ }
+ return u;
}
- ///
- /// Returns the list of Appointments from the database.
- ///
- public static List GetListOfAppointmentsForRadioTelescope(int radioTelescopeId)
+ ///
+ /// FOR TEST PURPOSES ONLY. Adds the new dummy admin to the database.
+ ///
+ public static void AddNewDummyUser()
{
- List appts = new List();
using (RTDbContext Context = InitializeDatabaseContext())
{
- // Use Include method to load related entities from the database
- appts = QueryAppointments(Context).Where(x => x.TelescopeId == radioTelescopeId).ToList();
+ Context.Database.ExecuteSqlCommand("INSERT INTO user (first_name, last_name, email_address, notification_type) VALUES ('control2', 'room', 'controlroom2@gmail.com', 'ALL')");
+ SaveContext(Context);
}
- return appts;
}
///
- /// Returns the updated Appointment from the database.
+ /// FOR TEST PURPOSES ONLY. Retrieves the dummy user from the database, if it does not already exist, to elevate to admin rank.
///
- public static Appointment GetUpdatedAppointment(int appt_id)
+ /// The dummy user
+ public static User GetDummyUser()
{
- Appointment appt;
+ User u = new User();
using (RTDbContext Context = InitializeDatabaseContext())
{
- List appts = new List();
- // Use Include method to load related entities from the database
- appts = QueryAppointments(Context).ToList();
- appt = appts.Find(x => x.Id == appt_id);
+ List testUserList = new List();
+ testUserList = Context.Users.SqlQuery("SELECT * FROM user WHERE (first_name = 'control2' AND last_name = 'room' AND email_address = 'controlroom2@gmail.com' AND notification_type = 'ALL')").ToList();
+ u = testUserList.First();
}
- return appt;
+ return u;
}
///
@@ -233,51 +323,162 @@ public static int GetTotalAppointmentCount()
return count;
}
+ ///
+ /// Returns the list of Appointments from the database.
+ ///
+ public static int GetTotalRTCount()
+ {
+ int count = -1;
+
+ using (RTDbContext Context = InitializeDatabaseContext())
+ {
+ count = Context.RadioTelescope.Count();
+ }
+
+ return count;
+ }
+
+ ///
+ /// Returns the updated Appointment from the database.
+ ///
+ public static Appointment GetUpdatedAppointment(Appointment appt)
+ {
+ using (RTDbContext Context = InitializeDatabaseContext())
+ {
+ // Because the celestial body is not required, we only want to
+ // perform these operations if one is present.
+ if (appt.celestial_body_id != null)
+ {
+ Context.Entry(appt.CelestialBody).State = EntityState.Unchanged;
+ if (appt.CelestialBody.Coordinate != null)
+ Context.Entry(appt.CelestialBody.Coordinate).State = EntityState.Unchanged;
+ }
+ if (appt.Orientation != null)
+ Context.Entry(appt.Orientation).State = EntityState.Unchanged;
+ Context.Entry(appt.SpectraCyberConfig).State = EntityState.Unchanged;
+ Context.Entry(appt.Telescope).State = EntityState.Unchanged;
+ Context.Entry(appt.User).State = EntityState.Unchanged;
+
+ Context.SaveChanges();
+
+ Context.Appointments.Attach(appt);
+
+ Context.Entry(appt).Reload();
+
+ }
+ return appt;
+ }
+
///
/// Creates and stores and RFData reading in the local database.
///
/// The RFData reading to be created/stored.
- public static void CreateRFData(int apptId, RFData data)
+ public static void AddRFData(RFData data)
{
if (VerifyRFData(data))
{
+
using (RTDbContext Context = InitializeDatabaseContext())
{
- var appt = Context.Appointments.Find(apptId);
- appt.RFDatas.Add(data);
- SaveContext(Context);
+
+ // add the rf data to the list in appointment
+ data.Appointment.RFDatas.Add(data);
+
+ // add the rf data to the database
+ Context.RFDatas.AddOrUpdate(data);
+
+ Context.Entry(data.Appointment.User).State = EntityState.Unchanged;
+ Context.Entry(data.Appointment).State = EntityState.Unchanged;
+ if (data.Appointment.Orientation != null)
+ Context.Entry(data.Appointment.Orientation).State = EntityState.Unchanged;
+ if (data.Appointment.CelestialBody != null)
+ {
+ if (data.Appointment.CelestialBody.Coordinate != null)
+ Context.Entry(data.Appointment.CelestialBody.Coordinate).State = EntityState.Unchanged;
+ Context.Entry(data.Appointment.CelestialBody).State = EntityState.Unchanged;
+ }
+ Context.Entry(data.Appointment.SpectraCyberConfig).State = EntityState.Unchanged;
+ Context.Entry(data.Appointment.Telescope).State = EntityState.Unchanged;
+
+ // Only perform the following operations on a real telescope
+ // (i.e. the fields will not be null)
+ if(data.Appointment.Telescope.Location != null)
+ Context.Entry(data.Appointment.Telescope.Location).State = EntityState.Unchanged;
+
+ if(data.Appointment.Telescope.CurrentOrientation != null)
+ Context.Entry(data.Appointment.Telescope.CurrentOrientation).State = EntityState.Unchanged;
+
+ if(data.Appointment.Telescope.CalibrationOrientation != null)
+ Context.Entry(data.Appointment.Telescope.CalibrationOrientation).State = EntityState.Unchanged;
+
+ Context.SaveChanges();
}
}
}
+ public static int GetTotalRFDataCount()
+ {
+ int count = -1;
+
+ using (RTDbContext Context = InitializeDatabaseContext())
+ {
+ count = Context.RFDatas.Count();
+ }
+
+ return count;
+ }
+
+ ///
+ /// Returns the list of Appointments from the database.
+ ///
+ public static List GetListOfRFData()
+ {
+ List appts = new List();
+ using (RTDbContext Context = InitializeDatabaseContext())
+ {
+ // Use Include method to load related entities from the database
+ appts = Context.RFDatas.Include(t => t.Appointment).ToList();
+
+ }
+ return appts;
+ }
+
///
/// Updates the appointment by saving the appt passed in.
///
/// The appt that is being updated.
public static void UpdateAppointment(Appointment appt)
- {
+ {
if (VerifyAppointmentStatus(appt))
{
using (RTDbContext Context = InitializeDatabaseContext())
{
- // Update database appt with new status
- var db_appt = QueryAppointments(Context).ToList().Find(x => x.Id == appt.Id);
- if (db_appt != null)
+ // Add appointment
+ Context.Appointments.AddOrUpdate(appt);
+
+ // Retrieve all coordinates for appointment
+ var coordsForAppt = Context.Coordinates.ToList().Where(coord => coord.apptId == appt.Id);
+
+ // Delete coordinates
+ foreach(Coordinate c in coordsForAppt)
{
- db_appt.CelestialBody = appt.CelestialBody;
- db_appt.Coordinates = appt.Coordinates;
- db_appt.EndTime = appt.EndTime;
- db_appt.Orientation = appt.Orientation;
- db_appt.RFDatas = appt.RFDatas;
- db_appt.SpectraCyberConfig = appt.SpectraCyberConfig;
- db_appt.StartTime = appt.StartTime;
- db_appt.Status = appt.Status;
- db_appt.TelescopeId = appt.TelescopeId;
- db_appt.Type = appt.Type;
- db_appt.UserId = appt.UserId;
- SaveContext(Context);
+ if (!appt.Coordinates.Any(co => co.Id == c.Id))
+ {
+ Context.Coordinates.Remove(c);
+ Context.SaveChangesAsync();
+ }
}
+
+ // Add coordinates
+ foreach (Coordinate c in appt.Coordinates)
+ {
+ c.apptId = appt.Id;
+ Context.Coordinates.AddOrUpdate(c);
+ }
+
+ Context.SaveChangesAsync();
+
}
}
}
@@ -291,19 +492,18 @@ public static Appointment GetNextAppointment(int radioTelescopeId)
Appointment appointment = null;
using (RTDbContext Context = InitializeDatabaseContext())
{
- //logger.Debug("Retrieving list of appointments.");
+ //logger.Debug(Utilities.GetTimeStamp() + ": Retrieving list of appointments.");
List appointments = GetListOfAppointmentsForRadioTelescope(radioTelescopeId);
if (appointments.Count > 0)
{
- appointments.RemoveAll(x => x.StartTime < DateTime.UtcNow || x.Status == AppointmentStatusEnum.COMPLETED);
+ appointments.RemoveAll(x => x._Status == AppointmentStatusEnum.COMPLETED || x._Status == AppointmentStatusEnum.CANCELED || x._Status == AppointmentStatusEnum.REQUESTED);
appointments.Sort();
- logger.Debug("Appointment list sorted. Starting to retrieve the next chronological appointment.");
appointment = appointments.Count > 0 ? appointments[0] : null;
}
else
{
- //logger.Debug("No appointments found");
+ //logger.Debug(Utilities.GetTimeStamp() + ": No appointments found");
}
}
@@ -340,44 +540,150 @@ private static bool VerifyRFData(RFData data)
/// A boolean indicating whether or not the status is valid.
private static bool VerifyAppointmentStatus(Appointment appt)
{
- return appt.Status.Equals(AppointmentStatusEnum.CANCELLED) ||
- appt.Status.Equals(AppointmentStatusEnum.COMPLETED) ||
- appt.Status.Equals(AppointmentStatusEnum.IN_PROGRESS) ||
- appt.Status.Equals(AppointmentStatusEnum.REQUESTED) ||
- appt.Status.Equals(AppointmentStatusEnum.SCHEDULED);
+ return appt._Status.Equals(AppointmentStatusEnum.CANCELED) ||
+ appt._Status.Equals(AppointmentStatusEnum.COMPLETED) ||
+ appt._Status.Equals(AppointmentStatusEnum.IN_PROGRESS) ||
+ appt._Status.Equals(AppointmentStatusEnum.REQUESTED) ||
+ appt._Status.Equals(AppointmentStatusEnum.SCHEDULED);
}
+
///
/// add an array of sensor data to the apropriat table
///
///
- public static void AddSensorData( List temp ) {
- if(temp.Count <= 0) { return; }
- if(!USING_REMOTE_DATABASE) {
- using(RTDbContext Context = InitializeDatabaseContext()) {
- Context.Temperatures.AddRange( temp );
- //foreach(Temperature tump in temp) {}
- SaveContext( Context );
+ public static void AddSensorData(Temperature[] temp, bool testflag = false)
+ {
+ Thread t = new Thread(() =>
+ {
+ if (temp.Length <= 0) { return; }
+ if (!USING_REMOTE_DATABASE)
+ {
+ using (RTDbContext Context = InitializeDatabaseContext())
+ {
+ Context.Temperatures.AddRange(temp);
+ //foreach(Temperature tump in temp) {}
+ SaveContext(Context);
+ }
}
- }
+ });
+
+ t.Start();
+
+ if (testflag) t.Join();
}
+ ///
+ /// add an array of sensor data to the apropriat table
+ ///
+ ///
+ public static void AddSensorData(Acceleration[] acc, bool testflag = false)
+ {
+ Thread t = new Thread(() =>
+ {
+ if (acc.Length <= 0) { return; }
+ if (!USING_REMOTE_DATABASE)
+ {
+ using (RTDbContext Context = InitializeDatabaseContext())
+ {
+ Context.Accelerations.AddRange(acc);
+ //foreach(Temperature tump in temp) {}
+ SaveContext(Context);
+ }
+ }
+ });
+
+ t.Start();
+
+ if (testflag) t.Join();
+ }
+
+ ///
+ /// add an Blob of acceleration data to the apropriate table
+ ///
+ ///
+ ///
+ ///
+ public static void AddAccelerationBlobData(AccelerationBlob acc, SensorLocationEnum location, bool testflag = false)
+ {
+ Thread t = new Thread(() =>
+ {
+
+ if (!USING_REMOTE_DATABASE)
+ {
+ using (RTDbContext Context = InitializeDatabaseContext())
+ {
+ //based on the specified location enum, add the blob to the corret table
+ switch (location)
+ {
+ case SensorLocationEnum.AZ_MOTOR:
+ Context.AzimuthAccelerationBlobs.Add((AzimuthAccelerationBlob)acc);
+ break;
+
+ case SensorLocationEnum.COUNTERBALANCE:
+ Context.CounterbalanceAccelerationBlobs.Add((CounterbalanceAccelerationBlob)acc);
+ break;
+
+ case SensorLocationEnum.EL_MOTOR:
+ Context.ElevationAccelerationBlobs.Add((ElevationAccelerationBlob)acc);
+ break;
+ }
- public static void AddSensorData( List acc ) {
- if(acc.Count <= 0) { return; }
- if(!USING_REMOTE_DATABASE) {
- using(RTDbContext Context = InitializeDatabaseContext()) {
- Context.Accelerations.AddRange( acc );
- //foreach(Temperature tump in temp) {}
- SaveContext( Context );
+ SaveContext(Context);
+ }
}
+ });
+
+ t.Start();
+
+ if (testflag) t.Join();
+ }
+
+ ///
+ /// get acc between starttime and now from sensor location loc
+ ///
+ ///
+ /// currently unused
+ ///
+ ///
+ public static List GetACCData(long starttime, long endTime, SensorLocationEnum loc)
+ {
+ using (RTDbContext Context = InitializeDatabaseContext())
+ {//&& x.TimeCaptured < endTime
+ return Context.Accelerations.Where(x => x.TimeCaptured > starttime && x.location_ID == (int)loc).ToList();
}
}
- public static List GetACCData( long starttime , long endTime, SensorLocationEnum loc ) {
+ //returns the Azimuth Acc Blobs between the start and end times
+ public static List GetAzAccBlobData( long starttime , long endTime) {
using(RTDbContext Context = InitializeDatabaseContext()) {//&& x.TimeCaptured < endTime
- return Context.Accelerations.Where( x => x.TimeCaptured > starttime && x.location_ID == (int)loc ).ToList();
+ return Context.AzimuthAccelerationBlobs.Where( x => x.FirstTimeCaptured >= starttime && x.FirstTimeCaptured <= endTime).ToList();
+ }
+ }
+
+ //returns the Counterbalance Acc Blobs between the start and end times
+ public static List GetCbAccBlobData(long starttime, long endTime)
+ {
+ using (RTDbContext Context = InitializeDatabaseContext())
+ {//&& x.TimeCaptured < endTime
+ return Context.CounterbalanceAccelerationBlobs.Where(x => x.FirstTimeCaptured >= starttime && x.FirstTimeCaptured <= endTime).ToList();
+ }
+ }
+
+ //returns the Elevation Acc Blobs between the start and end times
+ public static List GetElAccBlobData(long starttime, long endTime)
+ {
+ using (RTDbContext Context = InitializeDatabaseContext())
+ {//&& x.TimeCaptured < endTime
+ return Context.ElevationAccelerationBlobs.Where(x => x.FirstTimeCaptured >= starttime && x.FirstTimeCaptured <= endTime).ToList();
}
}
+ ///
+ /// get temp between starttime and now from sensor location loc
+ ///
+ ///
+ ///
+ ///
+ ///
public static List GetTEMPData( long starttime , long endTime, SensorLocationEnum loc ) {
using(RTDbContext Context = InitializeDatabaseContext()) {// && x.TimeCaptured < endTime) ) && x.TimeCaptured.Ticks < endTime.Ticks
return Context.Temperatures.Where( x => x.TimeCapturedUTC > starttime && x.location_ID == (int)loc ).ToList();
@@ -398,5 +704,326 @@ public static Temperature GetCurrentTemp( SensorLocationEnum loc ) {
}
}
}
+
+ ///
+ /// Adds the weather data
+ ///
+ public static void AddWeatherData(WeatherData weather)
+ {
+ using (RTDbContext Context = InitializeDatabaseContext())
+ {
+ Context.Weather.Add(weather);
+ SaveContext(Context);
+ }
+ }
+
+ ///
+ /// Adds the sensor status data
+ ///
+ public static void AddSensorStatusData(SensorStatus sensors)
+ {
+ using (RTDbContext Context = InitializeDatabaseContext())
+ {
+ Context.SensorStatus.Add(sensors);
+ SaveContext(Context);
+
+ //logger.Info(Utilities.GetTimeStamp() + ": Added sensor status data to database");
+ }
+ }
+
+ ///
+ /// Grabs the current threshold value from the database for the specific sensor
+ ///
+ public static double GetThresholdForSensor(SensorItemEnum item)
+ {
+ double val;
+ using (RTDbContext Context = InitializeDatabaseContext())
+ {
+ List thresholds = Context.ThresholdValues.Where(t => t.sensor_name == item.ToString()).ToList();
+
+ if (thresholds.Count() != 1)
+ {
+ throw new InvalidOperationException();
+ }
+
+ val = Convert.ToDouble(thresholds[0].maxValue);
+ }
+
+ return val;
+ }
+
+ ///
+ /// Updates the current override to whatever is provided
+ ///
+ public static void SetOverrideForSensor(SensorItemEnum item, bool doOverride)
+ {
+ using (RTDbContext Context = InitializeDatabaseContext())
+ {
+ var overrides = Context.Override.Where(t => t.sensor_name == item.ToString()).ToList();
+
+ if(overrides.Count() != 1)
+ {
+ throw new InvalidOperationException();
+ }
+
+ Override current = overrides[0];
+ current.Overridden = Convert.ToSByte(doOverride);
+
+ Context.Override.AddOrUpdate(current);
+
+ Context.SaveChangesAsync();
+ }
+ }
+
+ ///
+ /// Gets the current status of the override
+ ///
+ public static bool GetOverrideStatusForSensor(SensorItemEnum item)
+ {
+ Override current;
+ using (RTDbContext Context = InitializeDatabaseContext())
+ {
+ var overrides = Context.Override.Where(t => t.sensor_name == item.ToString()).ToList();
+
+ if (overrides.Count() != 1)
+ {
+ throw new InvalidOperationException();
+ }
+
+ current = overrides[0];
+ }
+
+ return current.Overridden == 1;
+ }
+
+ ///
+ /// Adds the radio telescope
+ ///
+ public static void AddRadioTelescope(RadioTelescope telescope)
+ {
+ using (RTDbContext Context = InitializeDatabaseContext())
+ {
+ Context.RadioTelescope.Add(telescope);
+ SaveContext(Context);
+
+ logger.Info(Utilities.GetTimeStamp() + ": Added radio telescope to database");
+ }
+ }
+
+ ///
+ /// Retrieves the lowest 'ID' radio telescope from the database
+ ///
+ public static RadioTelescope FetchFirstRadioTelescope()
+ {
+ using (RTDbContext Context = InitializeDatabaseContext())
+ {
+ var telescopes = Context.RadioTelescope
+ .Include(t => t.Location)
+ .Include(t => t.CalibrationOrientation)
+ .Include(t => t.CurrentOrientation)
+ .ToList();
+
+ foreach (RadioTelescope rt in telescopes)
+ {
+ logger.Info(Utilities.GetTimeStamp() + ": Retrieved Radio Telescope from the database");
+ return rt;
+ }
+
+ logger.Info(Utilities.GetTimeStamp() + ": No Radio Telescope found in the database");
+ return null;
+
+ }
+ }
+
+ ///
+ /// Method used to retrieve the last RadioTelescope found in the database
+ ///
+ /// last RadioTelescope instance found in the database
+ public static RadioTelescope FetchLastRadioTelescope()
+ {
+ using (RTDbContext Context = InitializeDatabaseContext())
+ {
+ var telescopes = Context.RadioTelescope
+ .Include(t => t.Location)
+ .Include(t => t.CalibrationOrientation)
+ .Include(t => t.CurrentOrientation)
+ .ToList();
+
+ return telescopes[telescopes.Count - 1];
+ }
+ }
+
+
+ ///
+ /// Function to retrieve a RT Instance in the database by a given ID
+ ///
+ /// ID of RadioTelescope inside the DB
+ /// RadioTelescope found in the database with the associated ID
+ /// Null, if the specified RT does not exist.
+ public static RadioTelescope FetchRadioTelescopeByID(int id)
+ {
+ using (RTDbContext Context = InitializeDatabaseContext())
+ {
+ var telescope = Context.RadioTelescope.
+ Include(t => t.Location)
+ .Include(t => t.CalibrationOrientation)
+ .Include(t => t.CurrentOrientation)
+ .Where(t => t.Id == id).FirstOrDefault();
+
+ if(telescope == null)
+ {
+ logger.Info(Utilities.GetTimeStamp() + ": The Radio Telescope with ID " + id + " could not be found.");
+ return null;
+ }
+ else
+ {
+ return telescope;
+ }
+ }
+
+
+ }
+
+ ///
+ /// Adds a new Sensor Network Configuration to the database
+ ///
+ public static void AddSensorNetworkConfig(SensorNetworkConfig config)
+ {
+ using (RTDbContext Context = InitializeDatabaseContext())
+ {
+ // First see if the config already exists (if Add was called by accident)
+ var testConf = Context.SensorNetworkConfig
+ .Where(c => c.TelescopeId == config.TelescopeId).FirstOrDefault();
+
+ // if it exists, forward the config to UpdateSensorNetworkConfig
+ if (testConf != null)
+ {
+ UpdateSensorNetworkConfig(config);
+ }
+ else
+ {
+ Context.SensorNetworkConfig.Add(config);
+ SaveContext(Context);
+
+ logger.Info(Utilities.GetTimeStamp() + $": Created Sensor Network Configuration for Radio Telescope {config.TelescopeId}");
+ }
+ }
+ }
+
+ ///
+ /// Returns a SensorNetworkConfig based on the RadioTelescope.Id provided.
+ ///
+ /// ID of the Radio Telescope the SensorNetworkConfig is related to
+ /// SensorNetworkConfig pertaining to a Radio Telescope; if none is found, null
+ public static SensorNetworkConfig RetrieveSensorNetworkConfigByTelescopeId(int telescopeId)
+ {
+ using (RTDbContext Context = InitializeDatabaseContext())
+ {
+ var config = Context.SensorNetworkConfig
+ .Where(c => c.TelescopeId == telescopeId).FirstOrDefault();
+
+ if (config == null)
+ {
+ logger.Info(Utilities.GetTimeStamp() + ": The Sensor Network Configuration for Telescope ID " + telescopeId + " could not be found.");
+ return null;
+ }
+ else
+ {
+ return config;
+ }
+ }
+ }
+
+ ///
+ /// This will update the sensor network configuration for a specific Telescope
+ ///
+ /// The SensorNetworkConfig to be updated
+ public static void UpdateSensorNetworkConfig(SensorNetworkConfig config)
+ {
+ using (RTDbContext Context = InitializeDatabaseContext())
+ {
+ var outdated = Context.SensorNetworkConfig
+ .Where(c => c.TelescopeId == config.TelescopeId).FirstOrDefault();
+
+ if (outdated == null)
+ {
+ throw new InvalidOperationException($"Cannot update config; no config found with a telescope of ID {config.TelescopeId}");
+ }
+ else
+ {
+ config.Id = outdated.Id;
+ Context.SensorNetworkConfig.AddOrUpdate(config);
+ SaveContext(Context);
+
+ logger.Info(Utilities.GetTimeStamp() + ": Updated Sensor Network Configuration for Telescope ID " + config.TelescopeId);
+ }
+ }
+ }
+
+ ///
+ /// Method used to delete a SensorNetworkConfig. This is not currently being
+ /// used in any production code, only for unit tests.
+ ///
+ /// The SensorNetworkConfig to be deleted.
+ public static void DeleteSensorNetworkConfig(SensorNetworkConfig config)
+ {
+ using (RTDbContext Context = InitializeDatabaseContext())
+ {
+ var toDelete = Context.SensorNetworkConfig
+ .Where(c => c.TelescopeId == config.TelescopeId).FirstOrDefault();
+
+ if (toDelete == null)
+ {
+ throw new InvalidOperationException($"Cannot delete config; no config found with a telescope of ID {config.TelescopeId}");
+ }
+ else
+ {
+ Context.SensorNetworkConfig.Attach(toDelete);
+ Context.SensorNetworkConfig.Remove(toDelete);
+ SaveContext(Context);
+
+ logger.Info(Utilities.GetTimeStamp() + ": Deleted Sensor Network Configuration for Telescope ID " + config.TelescopeId);
+ }
+ }
+ }
+ ///
+ /// Adds a selected weather Threshold to the database
+ ///
+ ///
+ public static void AddWeatherThreshold(WeatherThreshold weatherThreshold)
+ {
+ using (RTDbContext Context = InitializeDatabaseContext())
+ {
+ Context.WeatherThreshold.Add(weatherThreshold);
+ SaveContext(Context);
+
+ logger.Info(Utilities.GetTimeStamp() + ": Added WeatherThreshold to database");
+ }
+ }
+
+ ///
+ /// Routine to retrieve the time interval for dumping snow off of the dish (in minutes) from the database
+ ///
+ public static WeatherThreshold FetchWeatherThreshold()
+ {
+ using (RTDbContext Context = InitializeDatabaseContext())
+ {
+ var threshold = Context.WeatherThreshold.FirstOrDefault();
+
+
+ if (threshold == null)
+ {
+ logger.Info(Utilities.GetTimeStamp() + ": The WeatherThreshold data could not be found. Creating a new one with default values...");
+ // default values of 0 windSpeed and 2 hours for snow dump time. If the table is empty, add it
+ threshold = new WeatherThreshold(0, 120);
+ AddWeatherThreshold(threshold);
+ }
+ return threshold;
+
+ }
+
+ }
+
+
}
}
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/Database/RTDbContext.cs b/ControlRoomApplication/ControlRoomApplication/Database/RTDbContext.cs
index 7503ec86..c74d97cb 100644
--- a/ControlRoomApplication/ControlRoomApplication/Database/RTDbContext.cs
+++ b/ControlRoomApplication/ControlRoomApplication/Database/RTDbContext.cs
@@ -1,4 +1,5 @@
-using System.Data.Entity;
+using System;
+using System.Data.Entity;
using ControlRoomApplication.Constants;
using ControlRoomApplication.Entities;
@@ -8,7 +9,7 @@ public class RTDbContext : DbContext
{
public RTDbContext() : base(MiscellaneousConstants.LOCAL_DATABASE_NAME)
{
-
+
}
public RTDbContext(string connectionString) : base(connectionString)
@@ -17,14 +18,44 @@ public RTDbContext(string connectionString) : base(connectionString)
Configuration.LazyLoadingEnabled = false;
}
+ protected override void OnModelCreating(DbModelBuilder modelBuilder)
+ {
+
+ modelBuilder.Entity().HasOptional(t => t.CelestialBody).WithMany().Map(d => d.MapKey("celestial_body_id"));
+ modelBuilder.Entity().HasOptional(t => t.SpectraCyberConfig).WithMany().Map(d => d.MapKey("spectracyber_config_id"));
+ modelBuilder.Entity().HasOptional(t => t.Orientation).WithMany().Map(d => d.MapKey("orientation_id"));
+ modelBuilder.Entity().HasRequired(t => t.Telescope).WithMany().Map(d => d.MapKey("telescope_id"));
+ modelBuilder.Entity().HasRequired(t => t.User);
+
+ modelBuilder.Entity().HasRequired(t => t.Appointment).WithMany().Map(d => d.MapKey("appointment_id"));
+
+ // RadioTelescope
+ modelBuilder.Entity().HasRequired(t => t.Location);
+
+ }
+
public DbSet Appointments { get; set; }
public DbSet RFDatas { get; set; }
public DbSet Orientations { get; set; }
public DbSet Coordinates { get; set; }
+ public DbSet Location { get; set; }
public DbSet Logs { get; set; }
public DbSet Temperatures { get; set; }
public DbSet Accelerations { get; set; }
-
+ public DbSet AzimuthAccelerationBlobs { get; set; }
+ public DbSet ElevationAccelerationBlobs { get; set; }
+ public DbSet CounterbalanceAccelerationBlobs { get; set; }
+ public DbSet CelestialBodies { get; set; }
+ public DbSet SensorNetworkConfig { get; set; }
+ public DbSet SpectraCyberConfigs { get; set; }
+ public DbSet Users { get; set; }
+ public DbSet UserRoles { get; set; }
+ public DbSet Weather { get; set; }
+ public DbSet SensorStatus { get; set; }
+ public DbSet RadioTelescope { get; set; }
+ public DbSet ThresholdValues { get; set; }
+ public DbSet Override { get; set; }
+ public DbSet WeatherThreshold {get; set;}
}
}
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/Documentation/LoggerQueue.cs b/ControlRoomApplication/ControlRoomApplication/Documentation/LoggerQueue.cs
new file mode 100644
index 00000000..4bbecc8d
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Documentation/LoggerQueue.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ControlRoomApplication.Documentation
+{
+ public class LoggerQueue
+ {
+ public string loggerQueue;
+
+ public LoggerQueue()
+ {
+ loggerQueue = "";
+ }
+
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/Entities/Acceleration/AccelerationBlob.cs b/ControlRoomApplication/ControlRoomApplication/Entities/Acceleration/AccelerationBlob.cs
new file mode 100644
index 00000000..761c7476
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Entities/Acceleration/AccelerationBlob.cs
@@ -0,0 +1,247 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+using System.Text;
+using ControlRoomApplication.Constants;
+
+namespace ControlRoomApplication.Entities
+{
+ public abstract class AccelerationBlob
+ {
+ public abstract int Id { get; set; }
+
+ public abstract List BlobList { get; set; }
+
+ public abstract Byte[] BlobArray { get; set; }
+
+
+ public abstract long FirstTimeCaptured { get; set; }
+
+ private int NumberDataPoints { get; set; }
+
+ public virtual SensorLocationEnum Location { get; set; }
+
+ //takes an acceleration array along with other config data in order to blob together the data into a byte array
+ public virtual void BuildAccelerationBlob(Acceleration[] accArray, byte version = 1, byte FIFO_Size = 32, short SampleFrequency = 800, byte GRange = 16, Boolean FullResolution = true, bool testFlag = false)
+ {
+
+ //the switch statement is used for versioning of the blob, currently only one version exists, however; it is easy to add a new version
+ //by adding to a new case
+ switch (version)
+ {
+ case 1:
+ if (NumberDataPoints == 0)
+ {
+ //set the First Time Captured
+ FirstTimeCaptured = accArray[0].TimeCaptured;
+
+ //define the new List of Bytes
+ BlobList = new List();
+
+ //add the version to the start
+ BlobList.Add(version);
+
+ //add the fifo size to the start
+ BlobList.Add(FIFO_Size);
+
+ //add the sample frequency to the start
+ Byte[] frequencyBytes = BitConverter.GetBytes(SampleFrequency);
+ for(int i=0; i= MiscellaneousConstants.BLOB_SIZE)
+ {
+ BlobArray = BlobList.ToArray();
+ Database.DatabaseOperations.AddAccelerationBlobData(this, Location, true);
+ NumberDataPoints = 0;
+ }else if (testFlag) // if it is a test, only send it to an array so as to not mess with the DB
+ {
+ BlobArray = BlobList.ToArray();
+ NumberDataPoints = 0;
+ }
+
+ break;
+
+ case 2:
+ // if there ever is a second version of the blob, blobify it here
+ //currently no v2 so do nothing
+ break;
+ }
+ }
+
+ //takes an array of bytes in a given order to be able to parse into acceleration data
+ public virtual Acceleration[] BlobParser(Byte[] BlobToParse)
+ {
+ List accArrayList = new List();
+ //The blob has been designed in a modular way so that
+ //different versions can be blobbed and parsed. The first
+ //byte is dedicated to the version #
+ byte version = BlobToParse[0];
+
+ switch (version)
+ {
+ case 1:
+
+ //store teh FIFO size, sample frequency, GRange, and Full resolution for later use
+ byte FIFO_Size = BlobToParse[1];
+ short SampleFrequency = BitConverter.ToInt16(BlobToParse, 2);
+ byte GRange = BlobToParse[4];
+ Boolean FullResolution = BitConverter.ToBoolean(BlobToParse, 5);
+
+
+ //loop over the rest of the blob, the first byte in this section will be a label to tell us what
+ //to parse out of the blob next
+ for (int i = 6; i < BlobToParse.Length;)
+ {
+ char label = (char)BlobToParse[i];
+ i++;
+ Acceleration tempAcc = new Acceleration();
+
+ switch (label)
+ {
+ case 't':
+ //when the label is t, there is one time value and 3 acceleration values
+ tempAcc.TimeCaptured = BitConverter.ToInt64(BlobToParse, i) * 100;
+ i += 8;
+ tempAcc.x = BitConverter.ToInt16(BlobToParse, i);
+ i += 2;
+ tempAcc.y = BitConverter.ToInt16(BlobToParse, i);
+ i += 2;
+ tempAcc.z = BitConverter.ToInt16(BlobToParse, i);
+ i += 2;
+ tempAcc.acc = Math.Sqrt(tempAcc.x * tempAcc.x + tempAcc.y * tempAcc.y + tempAcc.z * tempAcc.z);
+ tempAcc.location_ID = (int)Location;
+ accArrayList.Add(tempAcc);
+ break;
+
+ case 'a':
+ //when the label is a, there are 3 acceleration values
+ tempAcc.TimeCaptured = accArrayList[accArrayList.Count - 1].TimeCaptured + ((1000 * 100) / SampleFrequency); /* 1000 / frequency = time offset, then * 100 to save precision */
+ tempAcc.x = BitConverter.ToInt16(BlobToParse, i);
+ i += 2;
+ tempAcc.y = BitConverter.ToInt16(BlobToParse, i);
+ i += 2;
+ tempAcc.z = BitConverter.ToInt16(BlobToParse, i);
+ i += 2;
+ tempAcc.acc = Math.Sqrt(tempAcc.x * tempAcc.x + tempAcc.y * tempAcc.y + tempAcc.z * tempAcc.z);
+ tempAcc.location_ID = (int)Location;
+ accArrayList.Add(tempAcc);
+ break;
+ }
+
+ }
+
+ break;
+
+ case 2:
+ //Parse the blob a different way if there is a 2nd version
+ break;
+
+ }
+
+ return accArrayList.ToArray();
+
+ }
+
+
+ //print the blob in binary form, used for visualization in presentations
+ public String blobToString(Byte[] blob)
+ {
+
+ string blobString = "";
+ foreach(byte b in blob)
+ {
+ string singleByte = Convert.ToString(b, 2).PadLeft(8, '0');
+ blobString += singleByte + " ";
+ }
+
+ return blobString;
+ }
+
+
+
+ }
+}
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/Entities/Acceleration/AzimuthAccelerationBlob.cs b/ControlRoomApplication/ControlRoomApplication/Entities/Acceleration/AzimuthAccelerationBlob.cs
new file mode 100644
index 00000000..a751f362
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Entities/Acceleration/AzimuthAccelerationBlob.cs
@@ -0,0 +1,42 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+using System.Text;
+using ControlRoomApplication.Constants;
+
+namespace ControlRoomApplication.Entities
+{
+ [Table("azimuth_acceleration_blob")]
+ public class AzimuthAccelerationBlob : AccelerationBlob
+ {
+ public AzimuthAccelerationBlob()
+ {
+ //StringBuilder added to create LongString of accelerartion to be strored in the databse seperated by -
+ NumberDataPoints = 0;
+ Location = SensorLocationEnum.AZ_MOTOR;
+ }
+
+ [Key]
+ [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+ public override int Id { get; set; }
+
+ [Required]
+ [Column("acc_blob")]
+ public override Byte[] BlobArray { get; set; }
+
+ [NotMapped]
+ public override List BlobList { get; set; }
+
+ [Required]
+ [Column("first_time_captured")]
+ public override long FirstTimeCaptured { get; set; }
+
+ [NotMapped]
+ public int NumberDataPoints { get; set; }
+
+ [NotMapped]
+ public override SensorLocationEnum Location { get; set; }
+
+ }
+}
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/Entities/Acceleration/CounterbalanceAccelerationBlob.cs b/ControlRoomApplication/ControlRoomApplication/Entities/Acceleration/CounterbalanceAccelerationBlob.cs
new file mode 100644
index 00000000..8f9d41b7
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Entities/Acceleration/CounterbalanceAccelerationBlob.cs
@@ -0,0 +1,41 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+using System.Text;
+using ControlRoomApplication.Constants;
+
+namespace ControlRoomApplication.Entities
+{
+ [Table("counterbalance_acceleration_blob")]
+ public class CounterbalanceAccelerationBlob : AccelerationBlob
+ {
+ public CounterbalanceAccelerationBlob()
+ {
+ //StringBuilder added to create LongString of accelerartion to be strored in the databse seperated by -
+ NumberDataPoints = 0;
+ Location = SensorLocationEnum.COUNTERBALANCE;
+ }
+
+ [Key]
+ [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+ public override int Id { get; set; }
+
+ [Required]
+ [Column("acc_blob")]
+ public override Byte[] BlobArray { get; set; }
+
+ [NotMapped]
+ public override List BlobList { get; set; }
+
+ [Required]
+ [Column("first_time_captured")]
+ public override long FirstTimeCaptured { get; set; }
+
+ [NotMapped]
+ public int NumberDataPoints { get; set; }
+
+ [NotMapped]
+ public override SensorLocationEnum Location { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/Entities/Acceleration/ElevationAccelerationBlob.cs b/ControlRoomApplication/ControlRoomApplication/Entities/Acceleration/ElevationAccelerationBlob.cs
new file mode 100644
index 00000000..b36bce84
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Entities/Acceleration/ElevationAccelerationBlob.cs
@@ -0,0 +1,42 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+using System.Text;
+using ControlRoomApplication.Constants;
+
+namespace ControlRoomApplication.Entities
+{
+ [Table("elevation_acceleration_blob")]
+ public class ElevationAccelerationBlob : AccelerationBlob
+ {
+ public ElevationAccelerationBlob()
+ {
+ //StringBuilder added to create LongString of accelerartion to be strored in the databse seperated by -
+ NumberDataPoints = 0;
+ Location = SensorLocationEnum.EL_MOTOR;
+ }
+
+ [Key]
+ [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+ public override int Id { get; set; }
+
+ [Required]
+ [Column("acc_blob")]
+ public override Byte[] BlobArray { get; set; }
+
+ [NotMapped]
+ public override List BlobList { get; set; }
+
+ [Required]
+ [Column("first_time_captured")]
+ public override long FirstTimeCaptured { get; set; }
+
+ [NotMapped]
+ public int NumberDataPoints { get; set; }
+
+ [NotMapped]
+ public override SensorLocationEnum Location { get; set; }
+
+ }
+}
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/Entities/Appointment/Appointment.cs b/ControlRoomApplication/ControlRoomApplication/Entities/Appointment/Appointment.cs
index f3602ef2..94b868d3 100644
--- a/ControlRoomApplication/ControlRoomApplication/Entities/Appointment/Appointment.cs
+++ b/ControlRoomApplication/ControlRoomApplication/Entities/Appointment/Appointment.cs
@@ -20,9 +20,8 @@ public Appointment()
{
Coordinates = new List();
RFDatas = new List();
- SpectraCyberConfig = new SpectraCyberConfig();
- Status = AppointmentStatusEnum.UNDEFINED;
- Type = AppointmentTypeEnum.UNDEFINED;
+ _Status = AppointmentStatusEnum.UNDEFINED;
+ _Type = AppointmentTypeEnum.UNDEFINED;
}
///
@@ -32,77 +31,188 @@ public Appointment()
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
- [Required]
- [Column("user_id")]
- public int UserId { get; set; }
+ ///
+ /// The getter/setter for the user id associated with this Appointment.
+ ///
+ public int user_id { get; set; }
+ [ForeignKey("user_id")]
+ public virtual User User { get; set; }
+
+
///
/// The getter/setter for the start time associated with this Appointment.
///
[Required]
[Column("start_time")]
- public DateTime StartTime { get; set; }
+ public DateTime start_time { get; set; }
///
/// The getter/setter for the end time associated with this Appointment.
///
[Required]
[Column("end_time")]
- public DateTime EndTime { get; set; }
+ public DateTime end_time { get; set; }
///
/// The getter/setter for the celestial body asscociated with this Appointment.
///
- [Column("celestial_body")]
- public CelestialBody CelestialBody { get; set; }
+ public int? celestial_body_id { get; set; }
+ [ForeignKey("celestial_body_id")]
+ public virtual CelestialBody CelestialBody { get; set; }
///
/// The getter/setter for the Orientation asscociated with this Appointment.
///
- [Column("orientation")]
- public Orientation Orientation { get; set; }
+ public int? orientation_id { get; set; }
+ [ForeignKey("orientation_id")]
+ public virtual Orientation Orientation { get; set; }
///
/// The getter/setter for the coordinates asscociated with this Appointment.
///
- [Required]
- [Column("coordinates")]
- public virtual ICollection Coordinates { get; set; }
+ // [Required]
+ // [Column("coordinates")]
+ [NotMapped]
+ public virtual ICollection Coordinates { get; set; } = new List();
///
/// The getter/setter for the RFData asscociated with this Appointment.
///
- [Required]
- [Column("rf_datas")]
- public virtual ICollection RFDatas { get; set; }
+ //[Required]
+ //[Column("rf_datas")]
+ [NotMapped]
+ public virtual ICollection RFDatas { get; set; } = new List();
+
+ [Column("public")]
+ public int Public { get; set; }
///
/// The getter/setter for the telescope asscociated with this Appointment.
///
- [Required]
- [Column("telescope_id")]
- public int TelescopeId { get; set; }
+ public int telescope_id { get;set; }
+ [ForeignKey("telescope_id")]
+ public virtual RadioTelescope Telescope { get; set; }
///
/// The getter/setter for the status asscociated with this Appointment.
+ /// This is the
///
+ [NotMapped]
+ public AppointmentStatusEnum _Status
+ {
+ get
+ {
+ return (AppointmentStatusEnum)Enum.Parse(typeof(AppointmentStatusEnum), status);
+ }
+ set
+ {
+ this.status = value.ToString();
+ }
+ }
+
+ private string backingStatus { get; set; }
+
[Required]
[Column("status")]
- public AppointmentStatusEnum Status { get; set; }
+ public string status {
+ get
+ {
+ return this.backingStatus;
+ }
+ set
+ {
+ if (value == null || Enum.IsDefined(typeof(AppointmentStatusEnum), value))
+ {
+ this.backingStatus = value;
+ }
+ else
+ {
+ throw new InvalidCastException();
+ }
+ }
+ }
///
/// The getter/setter for the Appointment type.
///
+ [NotMapped]
+ public AppointmentTypeEnum _Type {
+ get
+ {
+ return (AppointmentTypeEnum)Enum.Parse(typeof(AppointmentTypeEnum), type);
+ }
+ set
+ {
+ this.type = value.ToString();
+ }
+ }
+
+ private string backingType { get; set; }
+
[Required]
[Column("type")]
- public AppointmentTypeEnum Type { get; set; }
+ public string type {
+ get
+ {
+ return this.backingType;
+ }
+ set
+ {
+ if (value == null || Enum.IsDefined(typeof(AppointmentTypeEnum), value))
+ {
+ this.backingType = value;
+ }
+ else
+ {
+ throw new InvalidCastException();
+ }
+ }
+ }
///
- /// The getter/setter for the SpectraCyberConfig type.
+ /// The getter/setter for the Appointment priority type.
///
+ [NotMapped]
+ public AppointmentPriorityEnum _Priority {
+ get {
+ return (AppointmentPriorityEnum)Enum.Parse(typeof(AppointmentPriorityEnum), priority);
+ }
+ set
+ {
+ this.priority = value.ToString();
+ }
+ }
+
+ private string backingPriority {get; set;}
+
[Required]
- [Column("spectracyber_config")]
- public SpectraCyberConfig SpectraCyberConfig { get; set; }
+ [Column("priority")]
+ public string priority {
+ get
+ {
+ return this.backingPriority;
+ }
+ set
+ {
+ if (value == null || Enum.IsDefined(typeof(AppointmentPriorityEnum), value))
+ {
+ this.backingPriority = value;
+ }
+ else
+ {
+ throw new InvalidCastException();
+ }
+ }
+ }
+
+ ///
+ /// The getter/setter for the SpectraCyberConfig type.
+ ///
+ public int? spectracyber_config_id { get; set; }
+ [ForeignKey("spectracyber_config_id")]
+ public virtual SpectraCyberConfig SpectraCyberConfig { get; set; }
+
///
/// Compares the current Appointment to another object and it
@@ -135,7 +245,7 @@ public int CompareTo(Appointment other)
return 1;
}
// Use the DateTime Compare method to compare StartTimes
- return DateTime.Compare(StartTime, other.StartTime);
+ return DateTime.Compare(start_time, other.start_time);
}
///
@@ -173,12 +283,12 @@ public override bool Equals(object obj)
}
///
- /// Returns the HashCode of the Appointment's StartTime
+ /// Returns the HashCode of the Appointment's start_time
/// (Implemention of the IComparable Interface)
///
public override int GetHashCode()
{
- return StartTime.GetHashCode();
+ return start_time.GetHashCode();
}
///
diff --git a/ControlRoomApplication/ControlRoomApplication/Entities/Appointment/AppointmentPriorityEnum.cs b/ControlRoomApplication/ControlRoomApplication/Entities/Appointment/AppointmentPriorityEnum.cs
new file mode 100644
index 00000000..f31709e3
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Entities/Appointment/AppointmentPriorityEnum.cs
@@ -0,0 +1,10 @@
+
+namespace ControlRoomApplication.Entities
+{
+ public enum AppointmentPriorityEnum
+ {
+ PRIMARY,
+ SECONDARY,
+ MANUAL
+ }
+}
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/Entities/Appointment/AppointmentStatusEnum.cs b/ControlRoomApplication/ControlRoomApplication/Entities/Appointment/AppointmentStatusEnum.cs
index 5428b13b..ce6e7ae1 100644
--- a/ControlRoomApplication/ControlRoomApplication/Entities/Appointment/AppointmentStatusEnum.cs
+++ b/ControlRoomApplication/ControlRoomApplication/Entities/Appointment/AppointmentStatusEnum.cs
@@ -7,7 +7,7 @@ public enum AppointmentStatusEnum
REQUESTED,
SCHEDULED,
IN_PROGRESS,
- CANCELLED,
+ CANCELED,
COMPLETED
}
}
diff --git a/ControlRoomApplication/ControlRoomApplication/Entities/CelestialBody/CelestialBody.cs b/ControlRoomApplication/ControlRoomApplication/Entities/CelestialBody/CelestialBody.cs
index 4c9a89a9..b33aff5e 100644
--- a/ControlRoomApplication/ControlRoomApplication/Entities/CelestialBody/CelestialBody.cs
+++ b/ControlRoomApplication/ControlRoomApplication/Entities/CelestialBody/CelestialBody.cs
@@ -6,7 +6,6 @@
namespace ControlRoomApplication.Entities
{
[Table("celestial_body")]
- [Serializable]
public class CelestialBody
{
public CelestialBody(string name)
@@ -26,11 +25,15 @@ public CelestialBody() : this(CelestialBodyConstants.NONE) { }
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
- [Required]
+ // not nullable
[Column("name")]
public string Name { get; set; }
- [Column("coordinate")]
- public Coordinate Coordinate { get; set; }
+ // not nullable
+ public int coordinate_id { get; set; }
+ [ForeignKey("coordinate_id")]
+ public virtual Coordinate Coordinate { get; set; }
+
+
}
}
diff --git a/ControlRoomApplication/ControlRoomApplication/Entities/CelestialBody/CelestialBodyStatusEnum.cs b/ControlRoomApplication/ControlRoomApplication/Entities/CelestialBody/CelestialBodyStatusEnum.cs
new file mode 100644
index 00000000..828cb162
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Entities/CelestialBody/CelestialBodyStatusEnum.cs
@@ -0,0 +1,8 @@
+namespace ControlRoomApplication.Entities
+{
+ public enum CelestialBodyStatusEnum
+ {
+ HIDDEN,
+ VISIBLE
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/Entities/Configuration/MCUConfiguration.cs b/ControlRoomApplication/ControlRoomApplication/Entities/Configuration/MCUConfiguration.cs
new file mode 100644
index 00000000..598056d8
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Entities/Configuration/MCUConfiguration.cs
@@ -0,0 +1,52 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ControlRoomApplication.Entities.Configuration {
+ public class MCUConfigurationAxys {
+ ///
+ /// this is the minimum speed the MCU will travel at (RPM) , it is also start all moves at this speed befor accelerating, this should be fairly small
+ ///
+ public double StartSpeed = 0.06;
+ ///
+ /// timout of home comand 0 t0 300
+ ///
+ public int HomeTimeoutSec = 300;
+
+ public bool UseHomesensors = true;
+ public bool HomeActive_High = true;
+ ///
+ /// capture when capture is enabled and the capture input goes high the MCU will store its current position
+ ///
+ public bool UseCapture = false;
+ public bool CaptureActive_High = true;
+
+ public CW_CCW_input_use CWinput = CW_CCW_input_use.LimitSwitch;
+ public bool CWactive_High = false;
+ public CW_CCW_input_use CCWinput = CW_CCW_input_use.LimitSwitch;
+ public bool CCWactive_High = false;
+
+ public EncoderTyprEnum EncoderType = EncoderTyprEnum.Quadrature_Encoder;
+
+
+ }
+ ///
+ /// used to define the function and active state
+ ///
+ public enum CW_CCW_input_use {
+ NotUsed,
+ LimitSwitch,
+ EStop,
+ }
+
+ ///
+ /// used to define the function and active state
+ ///
+ public enum EncoderTyprEnum {
+ NotUsed,
+ Quadrature_Encoder,
+ Diagnostic_Feedback,
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/Entities/ControlRoom/ControlRoom.cs b/ControlRoomApplication/ControlRoomApplication/Entities/ControlRoom/ControlRoom.cs
index 10dbfc7e..089e4966 100644
--- a/ControlRoomApplication/ControlRoomApplication/Entities/ControlRoom/ControlRoom.cs
+++ b/ControlRoomApplication/ControlRoomApplication/Entities/ControlRoom/ControlRoom.cs
@@ -1,5 +1,7 @@
using System.Collections.Generic;
using ControlRoomApplication.Controllers;
+using System.Net;
+using ControlRoomApplication.Database;
namespace ControlRoomApplication.Entities
{
@@ -7,7 +9,9 @@ public class ControlRoom
{
public List RTControllerManagementThreads { get; }
public AbstractWeatherStation WeatherStation { get; }
-
+ public RemoteListener mobileControlServer { get; }
+ public int RemoteListenerPort { get; set; }
+ public bool weatherStationOverride { get; set; }
public List RadioTelescopeControllers
{
@@ -39,10 +43,13 @@ public List RadioTelescopes
}
}
- public ControlRoom(AbstractWeatherStation weatherStation)
+ public ControlRoom(AbstractWeatherStation weatherStation, int RemoteListenerPort)
{
+ this.RemoteListenerPort = RemoteListenerPort;
RTControllerManagementThreads = new List();
WeatherStation = weatherStation;
+ mobileControlServer = new RemoteListener(RemoteListenerPort, this);
+ weatherStationOverride = DatabaseOperations.GetOverrideStatusForSensor(SensorItemEnum.WEATHER_STATION);
}
}
}
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/Entities/Coordinate/Coordinate.cs b/ControlRoomApplication/ControlRoomApplication/Entities/Coordinate/Coordinate.cs
index bbccb73c..2068fb9e 100644
--- a/ControlRoomApplication/ControlRoomApplication/Entities/Coordinate/Coordinate.cs
+++ b/ControlRoomApplication/ControlRoomApplication/Entities/Coordinate/Coordinate.cs
@@ -10,6 +10,7 @@ public Coordinate(double rightAscension, double declination)
{
RightAscension = rightAscension;
Declination = declination;
+ apptId = -1;
}
public Coordinate() : this(0, 0) { }
@@ -25,5 +26,16 @@ public Coordinate() : this(0, 0) { }
[Required]
[Column("declination")]
public double Declination { get; set; }
+
+ [Required]
+ [Column("hours")]
+ public int hours { get; set; }
+
+ [Required]
+ [Column("minutes")]
+ public int minutes { get; set; }
+
+ [Column("appointment_id")]
+ public int apptId { get; set; }
}
}
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/Entities/DiagnosticData/Acceleration.cs b/ControlRoomApplication/ControlRoomApplication/Entities/DiagnosticData/Acceleration.cs
index a7688aa4..b04c9c6d 100644
--- a/ControlRoomApplication/ControlRoomApplication/Entities/DiagnosticData/Acceleration.cs
+++ b/ControlRoomApplication/ControlRoomApplication/Entities/DiagnosticData/Acceleration.cs
@@ -1,10 +1,12 @@
-using System;
+using ControlRoomApplication.Entities.DiagnosticData;
+using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace ControlRoomApplication.Entities {
[Table( "Acceleration" )]
- public class Acceleration {
+ public class Acceleration : IEquatable
+ {
public Acceleration() {
}
@@ -19,39 +21,61 @@ public Acceleration() {
public long TimeCaptured { get; set; }
[Required]
- [Column( "value" )]
+ [Column( "acceleration_magnitude" )]
public double acc { get; set; }
[Required]
- [Column( "x" )]
- public double x { get; set; }
+ [Column( "acceleration_x" )]
+ public int x { get; set; }
[Required]
- [Column( "y" )]
- public double y { get; set; }
+ [Column("acceleration_y")]
+ public int y { get; set; }
[Required]
- [Column( "z" )]
- public double z { get; set; }
+ [Column("acceleration_z")]
+ public int z { get; set; }
[Required]
[Column( "location" )]
public int location_ID { get; set; }
-
-
-
- public static Acceleration Generate( long UTCtics , double acc , double x , double y , double z , SensorLocationEnum loc ) {
+ public static Acceleration Generate( long UTCtics , int x , int y , int z , SensorLocationEnum loc ) {
Acceleration acx = new Acceleration();
acx.TimeCaptured = UTCtics;// Constants.TIME.UnixEpoch.AddMilliseconds( UTCtics );
- acx.acc = acc;
acx.x = x;
acx.y = y;
acx.z = z;
acx.location_ID = (int)loc;
+ acx.acc = Math.Sqrt(x * x + y * y + z * z);
return acx;
}
+ public bool Equals(Acceleration other)
+ {
+ if (x != other.x || y != other.y || z != other.z || location_ID != other.location_ID)
+ {
+ return false;
+ }
+ return true;
+ }
+
+ public static bool SequenceEquals(Acceleration[] start , Acceleration[] other)
+ {
+ if(start.Length != other.Length)
+ {
+ return false;
+ }
+
+ for (int i = 0; i < start.Length; i++)
+ {
+ if (start[i].x != other[i].x || start[i].y != other[i].y || start[i].z != other[i].z || start[i].location_ID != other[i].location_ID)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
}
}
diff --git a/ControlRoomApplication/ControlRoomApplication/Entities/DiagnosticData/Temperature.cs b/ControlRoomApplication/ControlRoomApplication/Entities/DiagnosticData/Temperature.cs
index 188e83c6..a904366a 100644
--- a/ControlRoomApplication/ControlRoomApplication/Entities/DiagnosticData/Temperature.cs
+++ b/ControlRoomApplication/ControlRoomApplication/Entities/DiagnosticData/Temperature.cs
@@ -1,10 +1,12 @@
-using System;
+using ControlRoomApplication.Entities.DiagnosticData;
+using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace ControlRoomApplication.Entities {
[Table( "Temperature" )]
- public class Temperature {
+ public class Temperature : IEquatable
+ {
public Temperature() {
}
@@ -17,9 +19,9 @@ public Temperature() {
[Required]
[Column( "time_captured" )]
public long TimeCapturedUTC { get; set; }
-
+
[Required]
- [Column( "value" )]
+ [Column( "temperature" )]
public double temp { get; set; }
[Required]
@@ -36,5 +38,13 @@ public static Temperature Generate( long UTCtics, double temperature , SensorLoc
return temp;
}
+ public bool Equals(Temperature other)
+ {
+ if(temp != other.temp || location_ID != other.location_ID)
+ {
+ return false;
+ }
+ return true;
+ }
}
}
diff --git a/ControlRoomApplication/ControlRoomApplication/Entities/Exceptions/MCUExceptions.cs b/ControlRoomApplication/ControlRoomApplication/Entities/Exceptions/MCUExceptions.cs
new file mode 100644
index 00000000..0576a950
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Entities/Exceptions/MCUExceptions.cs
@@ -0,0 +1,19 @@
+using ControlRoomApplication.Controllers;
+using ControlRoomApplication.Controllers.PLCCommunication.PLCDrivers.MCUManager;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ControlRoomApplication.Entities.Exceptions {
+ ///
+ /// raised when the MCU is exicuting a move that cannot be overriden
+ ///
+ public class MCUMoveOverlapException : Exception {
+ ///
+ /// this is the type of move that the MCU is currently running
+ ///
+ public MCUCommandType RunningMoveType;
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/Entities/HeartbeatInterface/HeartbeatInterface.cs b/ControlRoomApplication/ControlRoomApplication/Entities/HeartbeatInterface/HeartbeatInterface.cs
index 6da5c746..890ac5cc 100644
--- a/ControlRoomApplication/ControlRoomApplication/Entities/HeartbeatInterface/HeartbeatInterface.cs
+++ b/ControlRoomApplication/ControlRoomApplication/Entities/HeartbeatInterface/HeartbeatInterface.cs
@@ -96,7 +96,7 @@ protected void HeartbeatThreadRoutine()
}
// This is called to determine whether or not the component that this represents is responding to the system
- protected abstract bool TestIfComponentIsAlive();
+ public abstract bool TestIfComponentIsAlive();
// If this interface is failing to update appropriately or not hearing back as expected, this should be called
protected abstract bool KillHeartbeatComponent();
diff --git a/ControlRoomApplication/ControlRoomApplication/Entities/HeartbeatInterface/HeartbeatTracker.cs b/ControlRoomApplication/ControlRoomApplication/Entities/HeartbeatInterface/HeartbeatTracker.cs
index 1f2d76b9..90f60f66 100644
--- a/ControlRoomApplication/ControlRoomApplication/Entities/HeartbeatInterface/HeartbeatTracker.cs
+++ b/ControlRoomApplication/ControlRoomApplication/Entities/HeartbeatInterface/HeartbeatTracker.cs
@@ -58,5 +58,11 @@ public static HeartbeatTracker GetInstance()
return SINGLETON;
}
+ ///
+ /// only use this for tests
+ ///
+ public void clearHeartbeatTracker() {
+ Children.Clear();
+ }
}
}
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/Entities/HeartbeatInterface/HeartbeatTrackerContainer.cs b/ControlRoomApplication/ControlRoomApplication/Entities/HeartbeatInterface/HeartbeatTrackerContainer.cs
index 3763e9ac..61583de0 100644
--- a/ControlRoomApplication/ControlRoomApplication/Entities/HeartbeatInterface/HeartbeatTrackerContainer.cs
+++ b/ControlRoomApplication/ControlRoomApplication/Entities/HeartbeatInterface/HeartbeatTrackerContainer.cs
@@ -52,5 +52,9 @@ public static int GetNumberOfChildren()
{
return HeartbeatTracker.GetNumberOfChildren();
}
+
+ public static void clearChildren() {
+ HeartbeatTracker.clearHeartbeatTracker();
+ }
}
}
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/Entities/Location/Location.cs b/ControlRoomApplication/ControlRoomApplication/Entities/Location/Location.cs
index 7658af1d..a9de9dd3 100644
--- a/ControlRoomApplication/ControlRoomApplication/Entities/Location/Location.cs
+++ b/ControlRoomApplication/ControlRoomApplication/Entities/Location/Location.cs
@@ -6,11 +6,12 @@ namespace ControlRoomApplication.Entities
[Table("location")]
public class Location
{
- public Location(double longitude, double latitude, double altitude)
+ public Location(double longitude, double latitude, double altitude, string name)
{
Longitude = longitude;
Latitude = latitude;
Altitude = altitude;
+ Name = name;
}
public Location()
@@ -22,16 +23,19 @@ public Location()
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
- [Required]
+ //[Required]
[Column("longitude")]
- public double Longitude;
+ public double Longitude { get; set; }
- [Required]
+ //[Required]
[Column("latitude")]
- public double Latitude;
+ public double Latitude { get; set; }
- [Required]
+ //[Required]
[Column("altitude")]
- public double Altitude;
+ public double Altitude { get; set; }
+
+ [Column("name")]
+ public string Name { get; set; }
}
}
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/Entities/Location/SensorLocationEnum.cs b/ControlRoomApplication/ControlRoomApplication/Entities/Location/SensorLocationEnum.cs
index 1e10a6fa..c6e3b5e9 100644
--- a/ControlRoomApplication/ControlRoomApplication/Entities/Location/SensorLocationEnum.cs
+++ b/ControlRoomApplication/ControlRoomApplication/Entities/Location/SensorLocationEnum.cs
@@ -6,16 +6,21 @@
namespace ControlRoomApplication.Entities {
public enum SensorLocationEnum : int {
- UNDEFINED = -1,
- AZ_MOTOR = 0,
- EL_MOTOR = 1,
- END_OF_COUNTER_BALLENCE = 2,
- MICRO_CTRL = 3,
- MICRO_CTRL_BOX = 4
+ UNDEFINED,
+ AZ_MOTOR,
+ EL_MOTOR,
+ COUNTERBALANCE,
+ MICRO_CTRL,
+ MICRO_CTRL_BOX
}
public class SensorLocationEnumTypeConversionHelper {
+ ///
+ /// if input is not in SensorLocationEnum returns undefined
+ ///
+ ///
+ ///
public static SensorLocationEnum FromInt( int input ) {
if(!Enum.IsDefined( typeof( SensorLocationEnum ) , input )) {
return SensorLocationEnum.UNDEFINED;
diff --git a/ControlRoomApplication/ControlRoomApplication/Entities/Orientation/Orientation.cs b/ControlRoomApplication/ControlRoomApplication/Entities/Orientation/Orientation.cs
index f153b37d..26826da1 100644
--- a/ControlRoomApplication/ControlRoomApplication/Entities/Orientation/Orientation.cs
+++ b/ControlRoomApplication/ControlRoomApplication/Entities/Orientation/Orientation.cs
@@ -1,12 +1,13 @@
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
+using ControlRoomApplication.Constants;
namespace ControlRoomApplication.Entities
{
[Table("orientation")]
[Serializable]
- public class Orientation
+ public class Orientation : ICloneable
{
public Orientation(double azimuth, double elevation)
{
@@ -46,6 +47,23 @@ public override bool Equals(object obj)
return az_equal && el_equal;
}
+ ///
+ /// Checks if the current orientation is valid, based off of the max/min limit switch degrees
+ ///
+ ///
+ ///
+ public bool orientationValid()
+ {
+ if (
+ Elevation > SimulationConstants.LIMIT_HIGH_EL_DEGREES ||
+ Elevation < SimulationConstants.LIMIT_LOW_EL_DEGREES
+ )
+ {
+ return false;
+ }
+ return true;
+ }
+
///
/// Returns the HashCode of the Orientation's Id
///
@@ -53,5 +71,14 @@ public override int GetHashCode()
{
return Id.GetHashCode();
}
+
+ ///
+ /// An extension function to duplicate (clone) an orientation.
+ ///
+ /// Returns a new orientation identical to the object in which it was called.
+ public object Clone()
+ {
+ return new Orientation(Azimuth, Elevation);
+ }
}
}
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/Entities/Override/Override.cs b/ControlRoomApplication/ControlRoomApplication/Entities/Override/Override.cs
new file mode 100644
index 00000000..a4b651a8
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Entities/Override/Override.cs
@@ -0,0 +1,76 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+
+namespace ControlRoomApplication.Entities
+{
+ [Table("sensor_overrides")]
+ public class Override
+ {
+
+ [Key]
+ [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+ public int Id { get; set; }
+
+ [NotMapped]
+ public SensorItemEnum Item
+ {
+ get
+ {
+ return (SensorItemEnum)Enum.Parse(typeof(SensorItemEnum), sensor_name);
+ }
+ set
+ {
+ this.sensor_name = value.ToString();
+ }
+ }
+
+ private string backingName { get; set; }
+
+ [Required]
+ [Column("sensor_name")]
+ public string sensor_name
+ {
+ get
+ {
+ return this.backingName;
+ }
+ set
+ {
+ if (value == null || Enum.IsDefined(typeof(SensorItemEnum), value))
+ {
+ this.backingName = value;
+ }
+ else
+ {
+ throw new InvalidCastException();
+ }
+ }
+ }
+
+ [NotMapped]
+ public DateTime Time_Created { get; set; }
+
+ [NotMapped]
+ public String User_Created_By { get; set; }
+
+ [Column("overridden")]
+ public SByte Overridden { get; set; }
+
+ public Override(SensorItemEnum INItem, String createdBy)
+ {
+ Time_Created = DateTime.Now;
+ Item = INItem;
+ User_Created_By = createdBy;
+ }
+
+ public Override()
+ {
+
+ }
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/Entities/PLC/PLCCommandAndQueryTypeEnum.cs b/ControlRoomApplication/ControlRoomApplication/Entities/PLC/PLCCommandAndQueryTypeEnum.cs
index c6ae434c..74391201 100644
--- a/ControlRoomApplication/ControlRoomApplication/Entities/PLC/PLCCommandAndQueryTypeEnum.cs
+++ b/ControlRoomApplication/ControlRoomApplication/Entities/PLC/PLCCommandAndQueryTypeEnum.cs
@@ -2,78 +2,136 @@
namespace ControlRoomApplication.Entities
{
- public enum PLCCommandAndQueryTypeEnum : byte
- {
- UNDEFINED = 0x0,
- TEST_CONNECTION = 0x1,
- GET_CURRENT_AZEL_POSITIONS = 0x2,// remove, encoders not handled by plc anymore
- GET_CURRENT_LIMIT_SWITCH_STATUSES = 0x3,
- GET_CURRENT_SAFETY_INTERLOCK_STATUS = 0x4,
- CANCEL_ACTIVE_OBJECTIVE_AZEL_POSITION = 0x5,
- SHUTDOWN = 0x6,
- CALIBRATE = 0x7,
- SET_CONFIGURATION = 0x8,
- CONTROLLED_STOP = 0x9,
- IMMEDIATE_STOP= 0xA,
- SET_OBJECTIVE_AZEL_POSITION = 0xB,
- START_JOG_MOVEMENT = 0xC,
- TRANSLATE_AZEL_POSITION = 0xD
- }
-
- public class PLCCommandAndQueryTypeConversionHelper
- {
- public static PLCCommandAndQueryTypeEnum GetFromByte(byte input)
- {
- if (!Enum.IsDefined(typeof(PLCCommandAndQueryTypeEnum), input))
- {
- return PLCCommandAndQueryTypeEnum.UNDEFINED;
- }
- else
- {
- return (PLCCommandAndQueryTypeEnum)input;
- }
- }
-
- public static byte ConvertToByte(PLCCommandAndQueryTypeEnum input)
- {
- if (!Enum.IsDefined(typeof(PLCCommandAndQueryTypeEnum), input))
- {
- return ConvertToByte(PLCCommandAndQueryTypeEnum.UNDEFINED);
- }
- else
- {
- return (byte)input;
- }
- }
- }
-
-
///
/// the cctrlroom has a modbus server running on it that is maped to input and output regs on the plc
/// 0-20 arr comand bytes that go through the plc to the mcu
/// warnings, limits and other boolean values are sent as ints with 0 for false and 1 for true
- ///
///
+ ///
+ /// the registers in the PLC start at 0 however the registers in the controll room start at one
+ /// so an offset between the register number in the PLC and the number in the controll room is required
+ ///
public enum PLC_modbus_server_register_mapping : ushort
{
///
- /// plc will write to this register to acknoldge that a comand has been routed through the plc to the mcu
+ /// OUT
+ /// the PLC will not honor any requests to override the limits,
+ /// this is only a formality and testing
+ ///
+ LIMIT_OVERRIDE = 0+1,
+ ///
+ /// OUT
+ /// when this is set the elescope will still move even with the gate open
+ ///
+ GATE_OVERRIDE = 1+1,
+ ///
+ /// OUT
+ /// the PLC will never honor this request under any circumstances,
+ /// this mainly serves as a place holder
+ ///
+ E_STOP_OVERRIDE = 2+1,
+ ///
+ /// OUT
+ /// this word (ushort) is incramented every 1 second by the PLCDriver and is used by the PLC to determine if the control room is active
+ ///
+ CTRL_HEART_BEAT = 3+1,
+ ///
+ /// OUT
+ /// when this word is changed the PLC will shutDown the MCU
+ ///
+ MCU_RESET = 4+1,
+
+
+ ///
+ /// IN
+ /// limit at -10
+ ///
+ AZ_0_LIMIT = 8 + 1, /// Azimuth proximity sensor 1
+ ///
+ /// IN
+ /// limit at 375 degrees
+ ///
+ AZ_375_LIMIT = 9 + 1, /// Azimuth proximity sensor 2
+ ///
+ /// IN
+ /// home sensor at 0 degrees,
+ /// will be active between -15 and 0
+ ///
+ AZ_0_HOME = 10 + 1,
+ ///
+ /// IN
+ /// SECONDARY home sensor at 0 degrees,
+ /// will be active between -1 and 15
+ ///
+ AZ_0_SECONDARY = 11 + 1,
+
+
+ ///
+ /// IN
+ /// limit switch at -10
+ ///
+ ///
+ /// im not 100% certian that the telesope will actually have this switch
+ ///
+ EL_10_LIMIT = 12 + 1, /// Elevation proximity sensor 1?
+ ///
+ /// IN
+ /// active between 0 and -15 degrees
+ ///
+ EL_0_HOME = 13 + 1,
+ ///
+ /// IN
+ /// limit at 90 degrees
///
- CMD_ACK = 0+1,
+ EL_90_LIMIT = 14 + 1, /// Elevation proximity sensor 2?
- AZ_LEFT_LIMIT = 8 + 1,
- AZ_LEFT_WARNING = 9 + 1,
- AZ_RIGHT_WARNING = 10 + 1,
- AZ_RIGHT_LIMIT = 11 + 1,
- EL_BOTTOM_LIMIT = 12 + 1,
- EL_BOTTOM_WARNING = 13 + 1,
- EL_TOP_WARNING = 14 + 1,
- EL_TOP_LIMIT = 15 + 1,
- Safty_INTERLOCK = 18 + 1,
+ ///
+ /// IN
+ /// emergency stop the plc will handle disabling the motors and MCU, the controll should re-configure (and posibly re-home) the MCU after this is ended
+ ///
+ E_STOP = 15 + 1,
+ ///
+ /// IN
+ /// high when gate is open
+ ///
+ Gate_Safety_INTERLOCK = 16 + 1,
+ ///
+ /// IN
+ /// high when the MCU has a fault on the AZ axsis
+ ///
+ AZ_MCU_FAULT = 17+1,
+ ///
+ /// IN
+ /// high when the MCU has a fault on the AZ axsis
+ ///
+ EL_MCU_FAULT = 18+1,
+ ///
+ /// IN
+ /// high when the azimuth motor has a fault
+ ///
+ AZ_MTR_DRIVER_FAULT = 19 + 1,
+ ///
+ /// IN
+ /// high when the ELEVATION motor has a fault
+ ///
+ EL_MTR_DRIVER_FAULT = 20 + 1,
+ ///
+ /// IN
+ /// the elevation will have a second sensor connected directly to the Elevation Frame
+ ///
+ EL_SLIP_CAPTURE = 21+1,
+
+
+ ///
+ /// not currerntly used by the PLC
+ ///
AZ_MOTOR_CURRENT = 40 + 1,
+ ///
+ /// not currerntly used by the PLC
+ ///
EL_MOTOR_CURRENT = 42 + 1
}
diff --git a/ControlRoomApplication/ControlRoomApplication/Entities/PLC/PLCCommandResponseExpectationEnum.cs b/ControlRoomApplication/ControlRoomApplication/Entities/PLC/PLCCommandResponseExpectationEnum.cs
deleted file mode 100644
index 09d0b97e..00000000
--- a/ControlRoomApplication/ControlRoomApplication/Entities/PLC/PLCCommandResponseExpectationEnum.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-using System;
-
-namespace ControlRoomApplication.Entities
-{
- public enum PLCCommandResponseExpectationEnum : byte
- {
- UNDEFINED = 0x0,
- MINOR_RESPONSE = 0x1,
- FULL_RESPONSE = 0x2
- }
-
- public class PLCCommandResponseExpectationConversionHelper
- {
- public static PLCCommandResponseExpectationEnum GetFromByte(byte input)
- {
- if (!Enum.IsDefined(typeof(PLCCommandResponseExpectationEnum), input))
- {
- return PLCCommandResponseExpectationEnum.UNDEFINED;
- }
- else
- {
- return (PLCCommandResponseExpectationEnum)input;
- }
- }
-
- public static byte ConvertToByte(PLCCommandResponseExpectationEnum input)
- {
- if (!Enum.IsDefined(typeof(PLCCommandResponseExpectationEnum), input))
- {
- return ConvertToByte(PLCCommandResponseExpectationEnum.UNDEFINED);
- }
- else
- {
- return (byte)input;
- }
- }
- }
-}
diff --git a/ControlRoomApplication/ControlRoomApplication/Entities/RFData/RFData.cs b/ControlRoomApplication/ControlRoomApplication/Entities/RFData/RFData.cs
index 7d69d02d..485c5218 100644
--- a/ControlRoomApplication/ControlRoomApplication/Entities/RFData/RFData.cs
+++ b/ControlRoomApplication/ControlRoomApplication/Entities/RFData/RFData.cs
@@ -17,9 +17,9 @@ public RFData()
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
+ public int appointment_id { get; set; }
[ForeignKey("appointment_id")]
public virtual Appointment Appointment { get; set; }
- public int? appointment_id { get; set; }
[Required]
[Column("time_captured")]
@@ -27,7 +27,7 @@ public RFData()
[Required]
[Column("intensity")]
- public long Intensity { get; set; }
+ public double Intensity { get; set; }
//public Orientation AcquisitionOrientation { get; set; }
diff --git a/ControlRoomApplication/ControlRoomApplication/Entities/RadioTelescope/RadioTelescope.cs b/ControlRoomApplication/ControlRoomApplication/Entities/RadioTelescope/RadioTelescope.cs
index b4c7a95f..1f01ffce 100644
--- a/ControlRoomApplication/ControlRoomApplication/Entities/RadioTelescope/RadioTelescope.cs
+++ b/ControlRoomApplication/ControlRoomApplication/Entities/RadioTelescope/RadioTelescope.cs
@@ -1,13 +1,21 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using ControlRoomApplication.Controllers;
-using ControlRoomApplication.Controllers.BlkHeadUcontroler;
+using System;
+using ControlRoomApplication.Controllers.SensorNetwork;
+using ControlRoomApplication.Constants;
namespace ControlRoomApplication.Entities
{
[Table("radio_telescope")]
public class RadioTelescope
{
+
+ public RadioTelescope()
+ {
+
+ }
+
public RadioTelescope(AbstractSpectraCyberController spectraCyberController, AbstractPLCDriver plcCommsHandler, Location location, Orientation calibrationOrientation)
{
PLCDriver = plcCommsHandler;
@@ -15,45 +23,118 @@ public RadioTelescope(AbstractSpectraCyberController spectraCyberController, Abs
CalibrationOrientation = calibrationOrientation;
Location = location;
CurrentOrientation = new Orientation();
+ maxElevationDegrees = MiscellaneousConstants.MAX_SOFTWARE_STOP_EL_DEGREES;
+ minElevationDegrees = MiscellaneousConstants.MIN_SOFTWARE_STOP_EL_DEGREES;
}
- public RadioTelescope( AbstractSpectraCyberController spectraCyberController , AbstractPLCDriver plcCommsHandler , Location location , Orientation calibrationOrientation , int localDBID , AbstractMicrocontroller ctrler , AbstractEncoderReader encoder ) {
+ public RadioTelescope(AbstractSpectraCyberController spectraCyberController, AbstractPLCDriver plcCommsHandler, Location location, Orientation calibrationOrientation, int localDBID) {
PLCDriver = plcCommsHandler;
SpectraCyberController = spectraCyberController;
CalibrationOrientation = calibrationOrientation;
Location = location;
CurrentOrientation = new Orientation();
- Encoders = encoder;
- Micro_controler = ctrler;
Id = localDBID;
+ maxElevationDegrees = MiscellaneousConstants.MAX_SOFTWARE_STOP_EL_DEGREES;
+ minElevationDegrees = MiscellaneousConstants.MIN_SOFTWARE_STOP_EL_DEGREES;
}
- //
- // This is only to be used with a local DB instance!!
- //
- public RadioTelescope(AbstractSpectraCyberController spectraCyberController, AbstractPLCDriver plcCommsHandler, Location location, Orientation calibrationOrientation, int localDBID)
- : this(spectraCyberController, plcCommsHandler, location, calibrationOrientation)
+ public RadioTelescope(AbstractSpectraCyberController spectraCyberController, AbstractPLCDriver plcCommsHandler, Location location, Orientation calibrationOrientation, int localDBID, SensorNetworkServer sensorNetworkServer)
{
+ PLCDriver = plcCommsHandler;
+ SpectraCyberController = spectraCyberController;
+ CalibrationOrientation = calibrationOrientation;
+ Location = location;
+ CurrentOrientation = new Orientation();
Id = localDBID;
+ SensorNetworkServer = sensorNetworkServer;
+ maxElevationDegrees = MiscellaneousConstants.MAX_SOFTWARE_STOP_EL_DEGREES;
+ minElevationDegrees = MiscellaneousConstants.MIN_SOFTWARE_STOP_EL_DEGREES;
}
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
- [Column("id")]
- public int Id { get; }
+ public int Id { get; set; }
- [Column("current_orientation")]
- public Orientation CurrentOrientation { get; set; }
+ [Column("online")]
+ public int online { get; set; }
+
+ [Column("elevation_max_degree")]
+ public double maxElevationDegrees { get; set; }
- [Column("calibration_orientation")]
+ [Column("elevation_min_degree")]
+ public double minElevationDegrees { get; set; }
+
+ public int current_orientation_id { get; set; }
+ [ForeignKey("current_orientation_id")]
+ public Orientation CurrentOrientation { get; set; }
+
+ public int calibration_orientation_id { get; set; }
+ [ForeignKey("calibration_orientation_id")]
public Orientation CalibrationOrientation { get; set; }
- [Column("location")]
- public Location Location { get; set; }
+ public int location_id { get; set; }
+ [ForeignKey("location_id")]
+ public virtual Location Location { get; set; }
+ [NotMapped]
+ public RadioTelescopeTypeEnum _TeleType
+ {
+ get
+ {
+ return (RadioTelescopeTypeEnum)Enum.Parse(typeof(RadioTelescopeTypeEnum), teleType);
+ }
+ set
+ {
+ this.teleType = value.ToString();
+ }
+ }
+
+ private string backingTeleType { get; set; }
+
+ [Required]
+ [Column("telescope_type")]
+ public string teleType
+ {
+ get
+ {
+ return this.backingTeleType;
+ }
+ set
+ {
+ if (value == null || Enum.IsDefined(typeof(RadioTelescopeTypeEnum), value))
+ {
+ this.backingTeleType = value;
+ }
+ else
+ {
+ throw new InvalidCastException();
+ }
+ }
+ }
+
+ [NotMapped]
public AbstractPLCDriver PLCDriver { get; set; }
+
+ [NotMapped]
+ public SensorNetworkServer SensorNetworkServer { get; set; }
+
+ [NotMapped]
public AbstractSpectraCyberController SpectraCyberController { get; set; }
- public AbstractMicrocontroller Micro_controler { get; set; }
- public AbstractEncoderReader Encoders { get; set; }
+
+ [NotMapped]
+ protected RadioTelescopeController Parent;
+
+ public RadioTelescopeController GetParent()
+ {
+ return Parent;
+ }
+
+ public void SetParent(RadioTelescopeController rt)
+ {
+ Parent = rt;
+ }
+
+ [NotMapped]
+ public AbstractWeatherStation WeatherStation { get; set; }
}
}
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/Entities/RadioTelescope/RadioTelescopeConfig.cs b/ControlRoomApplication/ControlRoomApplication/Entities/RadioTelescope/RadioTelescopeConfig.cs
new file mode 100644
index 00000000..dc3363fe
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Entities/RadioTelescope/RadioTelescopeConfig.cs
@@ -0,0 +1,137 @@
+using System;
+using System.IO;
+using System.Text;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+
+
+namespace ControlRoomApplication.Entities
+{
+ ///
+ /// Data class for serializing and deserializing JSON strings into
+ /// RadioTelescopeConfig objects, used to tell the ControlRoom software
+ /// which telescope to run from the database given an ID.
+ ///
+ /// If no ID is given, the newTelescope flag is set which tells the
+ /// ControlRoom to create a new one.
+ ///
+ public class RadioTelescopeConfig
+ {
+ private static string FILE_NAME = "RadioTelescopeConfig.json";
+ private static string TEST_FILE_NAME = "RadioTelescopeConfigTest.json";
+ public static string DEFAULT_JSON_CONTENTS = "{\"telescopeID\":0,\"newTelescope\":true}";
+ public int telescopeID { get; set; }
+ public bool newTelescope { get; set; }
+
+ /// An integer representing the ID of a RadioTelescope instance to be retrived from the database
+ /// A boolean value to represent whether or not a new telescope should be created
+ public RadioTelescopeConfig(int telescopeID, bool newTelescope)
+ {
+ this.telescopeID = telescopeID;
+ this.newTelescope = newTelescope;
+ }
+
+
+ ///
+ /// Method to deserialize the output of the JSON file into a RadioTelescopConfig object.
+ /// File.ReadAllText is guranteed to close the file.
+ ///
+ /// null, if any errors occur in parsing or creating a new RT instance. Otherwise, it will return an instance of an RT
+ public static RadioTelescopeConfig DeserializeRTConfig(bool test = false)
+ {
+ string fileContents;
+ try
+ {
+ if (!test)
+ {
+ fileContents = File.ReadAllText(FILE_NAME);
+ }
+ else
+ {
+ fileContents = File.ReadAllText(TEST_FILE_NAME);
+ }
+
+ }catch(FileNotFoundException e)
+ {
+ if (!test)
+ {
+ CreateAndWriteToNewJSONFile(DEFAULT_JSON_CONTENTS, false);
+ fileContents = File.ReadAllText(FILE_NAME);
+ }
+ else
+ {
+ CreateAndWriteToNewJSONFile(DEFAULT_JSON_CONTENTS, true);
+ fileContents = File.ReadAllText(TEST_FILE_NAME);
+ }
+
+ }
+ RadioTelescopeConfig RTConfig;
+
+ // check to make sure JSON file contains valid JSON
+ try
+ {
+ JObject.Parse(fileContents);
+ RTConfig = JsonConvert.DeserializeObject(fileContents);
+ }
+ // file is either corrupted or contains invalid JSON. Return null if this is the case
+ catch(JsonReaderException e)
+ {
+ Console.WriteLine(e);
+ return null;
+ }
+ // also check to ensure the value was not null after parsing (if the user entered no value)
+ if(RTConfig.telescopeID.Equals(null) || RTConfig.newTelescope.Equals(null))
+ {
+ return null;
+ }
+
+ return RTConfig;
+ }
+
+ ///
+ /// Method to serialize an instance of RadioTelescopeConfig into JSON format and write it to the config file
+ ///
+ ///
+ public static void SerializeRTConfig(RadioTelescopeConfig RTConfig, bool test = false)
+ {
+ string toJson = JsonConvert.SerializeObject(RTConfig);
+ if (!test)
+ {
+ RadioTelescopeConfig.CreateAndWriteToNewJSONFile(toJson, false);
+ }
+ else
+ {
+ RadioTelescopeConfig.CreateAndWriteToNewJSONFile(toJson, true);
+ }
+
+
+ }
+
+
+ ///
+ /// Helper method to write to the JSON file, and create it if it does not exist.
+ ///
+ /// JSON Contents you wish to write to the JSON file
+ public static void CreateAndWriteToNewJSONFile(string fileContents, bool test = false)
+ {
+ // create the file if it does not exist, and write to it.
+ if (!test)
+ {
+ using (FileStream fs = File.Create(FILE_NAME))
+ {
+ byte[] contentsToBytes = new UTF8Encoding(true).GetBytes(fileContents);
+ fs.Write(contentsToBytes, 0, contentsToBytes.Length);
+ }
+ }
+ else
+ {
+ using (FileStream fs = File.Create(TEST_FILE_NAME))
+ {
+ byte[] contentsToBytes = new UTF8Encoding(true).GetBytes(fileContents);
+ fs.Write(contentsToBytes, 0, contentsToBytes.Length);
+ }
+ }
+
+ }
+ }
+}
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/Entities/RadioTelescope/RadioTelescopeDirectionEnum.cs b/ControlRoomApplication/ControlRoomApplication/Entities/RadioTelescope/RadioTelescopeDirectionEnum.cs
new file mode 100644
index 00000000..60203e0e
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Entities/RadioTelescope/RadioTelescopeDirectionEnum.cs
@@ -0,0 +1,33 @@
+namespace ControlRoomApplication.Entities
+{
+ ///
+ /// This will tell us what direction a motor is spinning on the telescope.
+ ///
+ public enum RadioTelescopeDirectionEnum
+ {
+ ///
+ /// The direction has not been specified. This should not be seen in production code.
+ ///
+ None,
+
+ ///
+ /// The motor is spinning clockwise (azimuth), or in a negative direction (elevation).
+ ///
+ ClockwiseOrNegative = 0x0080,
+
+ ///
+ /// The motor is spinning counter-clockwise (azimuth), or in a positive direction (elevation).
+ ///
+ CounterclockwiseOrPositive = 0x0100,
+
+ ///
+ /// The motor is spinning clockwise. This should ONLY be used for homing.
+ ///
+ ClockwiseHoming = 0x0020,
+
+ ///
+ /// The motor is spinning counterclockwise. This should ONLY be used for homing.
+ ///
+ CounterclockwiseHoming = 0x0040
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/Entities/RadioTelescope/RadioTelescopeTypeEnum.cs b/ControlRoomApplication/ControlRoomApplication/Entities/RadioTelescope/RadioTelescopeTypeEnum.cs
new file mode 100644
index 00000000..c81d2d30
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Entities/RadioTelescope/RadioTelescopeTypeEnum.cs
@@ -0,0 +1,23 @@
+namespace ControlRoomApplication.Entities
+{
+ ///
+ /// This will tell us whether the radio telescope has a slip ring or if it has hard stops.
+ ///
+ public enum RadioTelescopeTypeEnum
+ {
+ ///
+ /// This telescope has a slip ring, so it will have no limit switches on the azimuth axis.
+ ///
+ SLIP_RING,
+
+ ///
+ /// This telescope has hard stops, so it will have limit switches on the azimuth axis.
+ ///
+ HARD_STOPS,
+
+ ///
+ /// The telescope type has not been defiend. This should not be seen in production code.
+ ///
+ NONE
+ }
+}
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/Entities/Sensor/Sensor.cs b/ControlRoomApplication/ControlRoomApplication/Entities/Sensor/Sensor.cs
new file mode 100644
index 00000000..47c6e870
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Entities/Sensor/Sensor.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ControlRoomApplication.Entities
+{
+ public class Sensor
+ {
+ public SensorItemEnum Item { get; set; }
+ public DateTime Time_Created { get; set; }
+ public SensorStatusEnum Status { get; set; }
+
+ public Sensor(SensorItemEnum INItem, SensorStatusEnum status)
+ {
+ Time_Created = DateTime.Now;
+ Item = INItem;
+ Status = status;
+ }
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/Entities/Sensor/SensorItemEnum.cs b/ControlRoomApplication/ControlRoomApplication/Entities/Sensor/SensorItemEnum.cs
new file mode 100644
index 00000000..02df188a
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Entities/Sensor/SensorItemEnum.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ControlRoomApplication.Entities
+{
+ public enum SensorItemEnum
+ {
+ // general
+ GATE,
+ PROXIMITY,
+ AZIMUTH_MOTOR,
+ ELEVATION_MOTOR,
+ WEATHER_STATION,
+ EL_PROXIMITY_0,
+ EL_PROXIMITY_90,
+
+ // specific
+ AZ_MOTOR_TEMP,
+ ELEV_MOTOR_TEMP,
+ AZ_MOTOR_VIBRATION,
+ ELEV_MOTOR_VIBRATION,
+ AZ_MOTOR_CURRENT,
+ ELEV_MOTOR_CURRENT,
+ COUNTER_BALANCE_VIBRATION,
+ WIND,
+ RAIN_AMOUNT,
+ ELEVATION_ABS_ENCODER,
+ AZIMUTH_ABS_ENCODER
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/Entities/Sensor/SensorStatus.cs b/ControlRoomApplication/ControlRoomApplication/Entities/Sensor/SensorStatus.cs
new file mode 100644
index 00000000..9e2634aa
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Entities/Sensor/SensorStatus.cs
@@ -0,0 +1,54 @@
+using System;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+
+namespace ControlRoomApplication.Entities
+{
+ [Table("sensor_status")]
+ public class SensorStatus
+ {
+ public SensorStatus()
+ {
+
+ }
+
+ [Key]
+ [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+ public int Id { get; set; }
+
+
+ [Required]
+ [Column("gate")]
+ public SByte gate { get; set; }
+
+ [Required]
+ [Column("proximity")]
+ public SByte proximity { get; set; }
+
+ [Required]
+ [Column("azimuth_motor")]
+ public SByte az_motor { get; set; }
+
+ [Required]
+ [Column("elevation_motor")]
+ public SByte el_motor { get; set; }
+
+ [Required]
+ [Column("weather_station")]
+ public SByte weather { get; set; }
+
+
+ public static SensorStatus Generate(SensorStatusEnum gateEnum, SensorStatusEnum proximityEnum, SensorStatusEnum az_motorenum, SensorStatusEnum el_motor_enum, SensorStatusEnum weatherEnum)
+ {
+ SensorStatus status = new SensorStatus();
+
+ status.gate = Convert.ToSByte(gateEnum);
+ status.proximity = Convert.ToSByte(proximityEnum);
+ status.az_motor = Convert.ToSByte(az_motorenum);
+ status.el_motor = Convert.ToSByte(el_motor_enum);
+ status.weather = Convert.ToSByte(weatherEnum);
+
+ return status;
+ }
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/Entities/Sensor/SensorStatusEnum.cs b/ControlRoomApplication/ControlRoomApplication/Entities/Sensor/SensorStatusEnum.cs
new file mode 100644
index 00000000..8cd06f13
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Entities/Sensor/SensorStatusEnum.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ControlRoomApplication.Entities
+{
+ public enum SensorStatusEnum
+ {
+ NORMAL,
+ WARNING,
+ ALARM
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/Entities/Sensor/ThresholdValues.cs b/ControlRoomApplication/ControlRoomApplication/Entities/Sensor/ThresholdValues.cs
new file mode 100644
index 00000000..dc574daa
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Entities/Sensor/ThresholdValues.cs
@@ -0,0 +1,58 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+
+namespace ControlRoomApplication.Entities
+{
+ [Table("thresholds")]
+ public class ThresholdValues
+ {
+ [Key]
+ [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+ public int Id { get; set; }
+
+ [NotMapped]
+ public SensorItemEnum _Name
+ {
+ get
+ {
+ return (SensorItemEnum)Enum.Parse(typeof(SensorItemEnum), sensor_name);
+ }
+ set
+ {
+ this.sensor_name = value.ToString();
+ }
+ }
+
+ private string backingName { get; set; }
+
+ [Required]
+ [Column("sensor_name")]
+ public string sensor_name
+ {
+ get
+ {
+ return this.backingName;
+ }
+ set
+ {
+ if (value == null || Enum.IsDefined(typeof(SensorItemEnum), value))
+ {
+ this.backingName = value;
+ }
+ else
+ {
+ throw new InvalidCastException();
+ }
+ }
+ }
+
+ [Required]
+ [Column("maximum")]
+ public Single maxValue { get; set; }
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/Entities/SensorNetworkConfig/SensorNetworkConfig.cs b/ControlRoomApplication/ControlRoomApplication/Entities/SensorNetworkConfig/SensorNetworkConfig.cs
new file mode 100644
index 00000000..6c884569
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Entities/SensorNetworkConfig/SensorNetworkConfig.cs
@@ -0,0 +1,208 @@
+using ControlRoomApplication.Controllers.SensorNetwork;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ControlRoomApplication.Entities
+{
+
+ ///
+ /// This is the conviguration that the SensorNetworkServer and Client use.
+ /// This contains values that we want to be retained when the control
+ /// room is closed and then reopened, such as initialization information.
+ ///
+ [Table("sensor_network_config")]
+ public class SensorNetworkConfig : IEquatable
+ {
+ ///
+ /// Constructor to initialize a new SensorNetworkConfig for a RadioTelescope with default values.
+ ///
+ /// The RadioTelescope.Id that this configuration corresponds to.
+ public SensorNetworkConfig(int telescopeId)
+ {
+ TelescopeId = telescopeId;
+ TimeoutDataRetrieval = SensorNetworkConstants.DefaultDataRetrievalTimeout;
+ TimeoutInitialization = SensorNetworkConstants.DefaultInitializationTimeout;
+
+ // Initialize all sensors to enabled by default
+ ElevationTemp1Init = true;
+ AzimuthTemp1Init = true;
+ AzimuthAccelerometerInit = true;
+ ElevationAccelerometerInit = true;
+ CounterbalanceAccelerometerInit = true;
+ AzimuthEncoderInit = true;
+ ElevationEncoderInit = true;
+ }
+
+ ///
+ /// This constructor takes no parameters and sets all values to equivalents of 0.
+ /// It is only used for the Entity-MySql communication.
+ ///
+ public SensorNetworkConfig()
+ {
+ TelescopeId = 0;
+ TimeoutDataRetrieval = 0;
+ TimeoutInitialization = 0;
+
+ // Initialize all sensors to be disabled
+ ElevationTemp1Init = false;
+ AzimuthTemp1Init = false;
+ AzimuthAccelerometerInit = false;
+ ElevationAccelerometerInit = false;
+ CounterbalanceAccelerometerInit = false;
+ AzimuthEncoderInit = false;
+ ElevationEncoderInit = false;
+ }
+
+ ///
+ /// Database-generated id value. This has a uniqueness constraint (meaning that the Id in one SensorNetworkConfig
+ /// cannot be equal to the Id of another).
+ ///
+ [Key]
+ [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+ public int Id { get; set; }
+
+ ///
+ /// The Radio Telescope ID that this configuration is for. This should not be
+ /// a foreign key, because a SensorNetworkConfig does not have a whole RadioTelescope object.
+ ///
+ [Column("telescope_id")]
+ public int TelescopeId { get; set; }
+
+ ///
+ /// This will tell the Sensor Network whether or not to initialize the primary elevation motor temp sensor.
+ /// We will not receive data for this sensor if it is not initialized.
+ /// true = initialize;
+ /// false = do not initialize
+ ///
+ [Column("elevation_temp_1_init")]
+ public bool ElevationTemp1Init { get; set; }
+
+ ///
+ /// This will tell the Sensor Network whether or not to initialize the primary azimuth motor temp sensor.
+ /// We will not receive data for this sensor if it is not initialized.
+ /// true = initialize;
+ /// false = do not initialize
+ ///
+ [Column("azimuth_temp_1_init")]
+ public bool AzimuthTemp1Init { get; set; }
+
+ ///
+ /// This will tell the Sensor Network whether or not to initialize the azimuth accelerometer.
+ /// We will not receive data for this sensor if it is not initialized.
+ /// true = initialize;
+ /// false = do not initialize
+ ///
+ [Column("azimuth_accelerometer_init")]
+ public bool AzimuthAccelerometerInit { get; set; }
+
+ ///
+ /// This will tell the Sensor Network whether or not to initialize the elevation accelerometer.
+ /// We will not receive data for this sensor if it is not initialized.
+ /// true = initialize;
+ /// false = do not initialize
+ ///
+ [Column("elevation_accelerometer_init")]
+ public bool ElevationAccelerometerInit { get; set; }
+
+ ///
+ /// This will tell the Sensor Network whether or not to initialize the counterbalance accelerometer.
+ /// We will not receive data for this sensor if it is not initialized.
+ /// true = initialize;
+ /// false = do not initialize
+ ///
+ [Column("counterbalance_accelerometer_init")]
+ public bool CounterbalanceAccelerometerInit { get; set; }
+
+ ///
+ /// This will tell the Sensor Network whether or not to initialize the azimuth encoder.
+ /// We will not receive data for this sensor if it is not initialized.
+ /// true = initialize;
+ /// false = do not initialize
+ ///
+ [Column("azimuth_encoder_init")]
+ public bool AzimuthEncoderInit { get; set; }
+
+ ///
+ /// This will tell the Sensor Network whether or not to initialize the elevation encoder.
+ /// We will not receive data for this sensor if it is not initialized.
+ /// true = initialize;
+ /// false = do not initialize
+ ///
+ [Column("elevation_encoder_init")]
+ public bool ElevationEncoderInit { get; set; }
+
+ ///
+ /// The timeout interval, in seconds, that the telescope will go into a state of .
+ ///
+ [Column("timeout_data_retrieval")]
+ public int TimeoutDataRetrieval { get; set; }
+
+ ///
+ /// The timeout interval, in seconds, that the telescope will go into a state of .
+ ///
+ [Column("timeout_initialization")]
+ public int TimeoutInitialization { get; set; }
+
+ ///
+ /// This will check if two SensorNetworkConfigs are identical or not
+ ///
+ /// The SensorNetworkConfig to compare against
+ ///
+ public bool Equals(SensorNetworkConfig other)
+ {
+ // First do null checking
+ if (this == null && other == null) return true;
+ else if (this == null) return false;
+ else if (other == null) return false;
+
+ else if (
+ this.TelescopeId == other.TelescopeId &&
+ this.ElevationTemp1Init == other.ElevationTemp1Init &&
+ this.AzimuthTemp1Init == other.AzimuthTemp1Init &&
+ this.AzimuthAccelerometerInit == other.AzimuthAccelerometerInit &&
+ this.ElevationAccelerometerInit == other.ElevationAccelerometerInit &&
+ this.CounterbalanceAccelerometerInit == other.CounterbalanceAccelerometerInit &&
+ this.AzimuthEncoderInit == other.AzimuthEncoderInit &&
+ this.ElevationEncoderInit == other.ElevationEncoderInit &&
+ this.TimeoutDataRetrieval == other.TimeoutDataRetrieval &&
+ this.TimeoutInitialization == other.TimeoutInitialization)
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+
+ }
+
+ ///
+ /// This will be used to convert the current sensor initialization to a byte array that we
+ /// can send to the Sensor Network. It will convert each init to its own byte that will
+ /// be either 1 or 0.
+ /// 0 = not initialized;
+ /// 1 = initialized
+ ///
+ public byte[] GetSensorInitAsBytes()
+ {
+ byte[] init = new byte[] {
+ ElevationTemp1Init ? (byte)1 : (byte)0,
+ AzimuthTemp1Init ? (byte)1 : (byte)0,
+ ElevationEncoderInit ? (byte)1 : (byte)0,
+ AzimuthEncoderInit ? (byte)1 : (byte)0,
+ AzimuthAccelerometerInit ? (byte)1 : (byte)0,
+ ElevationAccelerometerInit ? (byte)1 : (byte)0,
+ CounterbalanceAccelerometerInit ? (byte)1 : (byte)0
+ };
+
+ return init;
+ }
+ }
+
+
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/Entities/SpectraCyber/AbstractSpectraCyber.cs b/ControlRoomApplication/ControlRoomApplication/Entities/SpectraCyber/AbstractSpectraCyber.cs
index 5c25d801..d578a0d6 100644
--- a/ControlRoomApplication/ControlRoomApplication/Entities/SpectraCyber/AbstractSpectraCyber.cs
+++ b/ControlRoomApplication/ControlRoomApplication/Entities/SpectraCyber/AbstractSpectraCyber.cs
@@ -4,13 +4,12 @@ public abstract class AbstractSpectraCyber
{
public SpectraCyberModeTypeEnum CurrentModeType { get; set; }
public SpectraCyberRequest CurrentSpectraCyberRequest { get; set; }
- public int ActiveAppointmentID { get; set; }
+ public Appointment ActiveAppointment { get; set; }
public AbstractSpectraCyber()
{
CurrentModeType = SpectraCyberModeTypeEnum.UNKNOWN;
CurrentSpectraCyberRequest = SpectraCyberRequest.GetNewEmpty();
- ActiveAppointmentID = -1;
}
}
}
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/Entities/SpectraCyber/SpectraCyberBandwidthEnum.cs b/ControlRoomApplication/ControlRoomApplication/Entities/SpectraCyber/SpectraCyberBandwidthEnum.cs
index a7f723a6..bcc3f204 100644
--- a/ControlRoomApplication/ControlRoomApplication/Entities/SpectraCyber/SpectraCyberBandwidthEnum.cs
+++ b/ControlRoomApplication/ControlRoomApplication/Entities/SpectraCyber/SpectraCyberBandwidthEnum.cs
@@ -4,7 +4,6 @@ public enum SpectraCyberBandwidthEnum
{
UNDEFINED,
SMALL_BANDWIDTH,
- MID_BANDWIDTH,
LARGE_BANDWIDTH
}
@@ -15,16 +14,43 @@ public static string GetValue(this SpectraCyberBandwidthEnum time)
switch (time)
{
case SpectraCyberBandwidthEnum.SMALL_BANDWIDTH:
- return "7.5";
- case SpectraCyberBandwidthEnum.MID_BANDWIDTH:
- return "15";
+ return "15Khz";
case SpectraCyberBandwidthEnum.LARGE_BANDWIDTH:
- return "30";
+ return "30Khz";
case SpectraCyberBandwidthEnum.UNDEFINED:
throw new System.Exception("UNDEFINED SpectraCyberBandwidthEnum type");
default:
throw new System.Exception("Unexpected SpectraCyberBandwidthEnum type");
}
}
+
+ public static SpectraCyberBandwidthEnum GetEnumFromValue(int value)
+ {
+ switch (value)
+ {
+ case 15:
+ return SpectraCyberBandwidthEnum.SMALL_BANDWIDTH;
+ case 1200:
+ return SpectraCyberBandwidthEnum.LARGE_BANDWIDTH;
+ default:
+ return SpectraCyberBandwidthEnum.UNDEFINED;
+ }
+ }
+
+ public static int GetIntegerValue(this SpectraCyberBandwidthEnum time)
+ {
+ switch (time)
+ {
+ case SpectraCyberBandwidthEnum.SMALL_BANDWIDTH:
+ return 15;
+ case SpectraCyberBandwidthEnum.LARGE_BANDWIDTH:
+ return 1200;
+ // case SpectraCyberBandwidthEnum.UNDEFINED:
+ // throw new System.Exception("UNDEFINED SpectraCyberBandwidthEnum type");
+ default:
+ return 30;
+ // throw new System.Exception("Unexpected SpectraCyberBandwidthEnum type");
+ }
+ }
}
}
diff --git a/ControlRoomApplication/ControlRoomApplication/Entities/SpectraCyber/SpectraCyberConfig.cs b/ControlRoomApplication/ControlRoomApplication/Entities/SpectraCyber/SpectraCyberConfig.cs
index d78b654b..a00aa302 100644
--- a/ControlRoomApplication/ControlRoomApplication/Entities/SpectraCyber/SpectraCyberConfig.cs
+++ b/ControlRoomApplication/ControlRoomApplication/Entities/SpectraCyber/SpectraCyberConfig.cs
@@ -5,13 +5,12 @@
namespace ControlRoomApplication.Entities
{
[Table("spectracyber_config")]
- [Serializable]
public class SpectraCyberConfig
{
public SpectraCyberConfig(SpectraCyberModeTypeEnum mode, SpectraCyberIntegrationTimeEnum integration_time,
double offset_voltage, double if_gain, SpectraCyberDCGainEnum dc_gain, SpectraCyberBandwidthEnum bandwidth)
{
- Mode = mode;
+ _Mode = mode;
IntegrationTime = integration_time;
OffsetVoltage = offset_voltage;
IFGain = if_gain;
@@ -21,7 +20,7 @@ public SpectraCyberConfig(SpectraCyberModeTypeEnum mode, SpectraCyberIntegration
public SpectraCyberConfig(SpectraCyberModeTypeEnum mode)
{
- Mode = mode;
+ _Mode = mode;
IntegrationTime = SpectraCyberIntegrationTimeEnum.MID_TIME_SPAN;
OffsetVoltage = 0;
IFGain = 10;
@@ -29,19 +28,64 @@ public SpectraCyberConfig(SpectraCyberModeTypeEnum mode)
Bandwidth = SpectraCyberBandwidthEnum.SMALL_BANDWIDTH;
}
- public SpectraCyberConfig() : this(SpectraCyberModeTypeEnum.UNKNOWN) { }
+ public SpectraCyberConfig() : this(SpectraCyberModeTypeEnum.SPECTRAL) { }
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
+ [NotMapped]
+ public SpectraCyberModeTypeEnum _Mode
+ {
+ get
+ {
+ return (SpectraCyberModeTypeEnum)Enum.Parse(typeof(SpectraCyberModeTypeEnum), mode);
+ }
+ set
+ {
+ this.mode = value.ToString();
+ }
+ }
+
+ private string backingMode { get; set; }
+
[Required]
[Column("mode")]
- public SpectraCyberModeTypeEnum Mode { get; set; }
+ public string mode
+ {
+ get
+ {
+ return this.backingMode;
+ }
+ set
+ {
+ if (value == null || Enum.IsDefined(typeof(SpectraCyberModeTypeEnum), value))
+ {
+ this.backingMode = value;
+ }
+ else
+ {
+ throw new InvalidCastException();
+ }
+ }
+ }
+
+ [NotMapped]
+ public SpectraCyberIntegrationTimeEnum IntegrationTime { get; set; }
[Required]
[Column("integration_time")]
- public SpectraCyberIntegrationTimeEnum IntegrationTime { get; set; }
+ public double time
+ {
+ get
+ {
+ return SpectraCyberIntegrationTimeEnumHelper.GetDoubleValue(IntegrationTime);
+ }
+ set
+ {
+ IntegrationTime = SpectraCyberIntegrationTimeEnumHelper.GetEnumFromValue(value);
+ }
+ }
[Required]
[Column("offset_voltage")]
@@ -51,14 +95,43 @@ public SpectraCyberConfig() : this(SpectraCyberModeTypeEnum.UNKNOWN) { }
[Column("if_gain")]
public double IFGain { get; set; }
- [Required]
- [Column("dc_gain")]
+ [NotMapped]
public SpectraCyberDCGainEnum DCGain { get; set; }
[Required]
- [Column("bandwidth")]
+ [Column("dc_gain")]
+ public int dc_gain
+ {
+ get
+ {
+ return SpectraCyberDCGainEnumHelper.GetIntegerValue(DCGain);
+ }
+ set
+ {
+ DCGain = SpectraCyberDCGainEnumHelper.GetEnumFromValue(value);
+ }
+ }
+
+ [NotMapped]
public SpectraCyberBandwidthEnum Bandwidth { get; set; }
+ // [Required]
+ // [Column("bandwidth")]
+ [NotMapped]
+ public int bandwidth
+ {
+ get
+ {
+ return SpectraCyberBandwidthEnumHelper.GetIntegerValue(Bandwidth);
+ }
+ set
+ {
+ Bandwidth = SpectraCyberBandwidthEnumHelper.GetEnumFromValue(value);
+ }
+ }
+
+
+
///
/// Checks if the current SpectraCyberConfig is Equal to another SpectraCyberConfig
/// and it checks if the other SpectraCyberConfig is null
@@ -70,7 +143,7 @@ public override bool Equals(object obj)
{
return false;
}
- return Mode == other.Mode &&
+ return _Mode == other._Mode &&
IntegrationTime == other.IntegrationTime &&
OffsetVoltage == other.OffsetVoltage &&
IFGain == other.IFGain &&
diff --git a/ControlRoomApplication/ControlRoomApplication/Entities/SpectraCyber/SpectraCyberDCGainEnum.cs b/ControlRoomApplication/ControlRoomApplication/Entities/SpectraCyber/SpectraCyberDCGainEnum.cs
index a255b6a6..4f618916 100644
--- a/ControlRoomApplication/ControlRoomApplication/Entities/SpectraCyber/SpectraCyberDCGainEnum.cs
+++ b/ControlRoomApplication/ControlRoomApplication/Entities/SpectraCyber/SpectraCyberDCGainEnum.cs
@@ -35,5 +35,49 @@ public static string GetValue(this SpectraCyberDCGainEnum time)
throw new System.Exception("Unexpected SpectraCyberDCGainEnum type");
}
}
+
+ public static SpectraCyberDCGainEnum GetEnumFromValue(int value)
+ {
+ switch (value)
+ {
+ case 1:
+ return SpectraCyberDCGainEnum.X1;
+ case 5:
+ return SpectraCyberDCGainEnum.X5;
+ case 10:
+ return SpectraCyberDCGainEnum.X10;
+ case 20:
+ return SpectraCyberDCGainEnum.X20;
+ case 50:
+ return SpectraCyberDCGainEnum.X50;
+ case 60:
+ return SpectraCyberDCGainEnum.X60;
+ default:
+ return SpectraCyberDCGainEnum.UNDEFINED;
+ }
+ }
+
+ public static int GetIntegerValue(this SpectraCyberDCGainEnum time)
+ {
+ switch (time)
+ {
+ case SpectraCyberDCGainEnum.X1:
+ return 1;
+ case SpectraCyberDCGainEnum.X5:
+ return 5;
+ case SpectraCyberDCGainEnum.X10:
+ return 10;
+ case SpectraCyberDCGainEnum.X20:
+ return 20;
+ case SpectraCyberDCGainEnum.X50:
+ return 50;
+ case SpectraCyberDCGainEnum.X60:
+ return 60;
+ case SpectraCyberDCGainEnum.UNDEFINED:
+ throw new System.Exception("UNDEFINED SpectraCyberDCGainEnum type");
+ default:
+ throw new System.Exception("Unexpected SpectraCyberDCGainEnum type");
+ }
+ }
}
}
diff --git a/ControlRoomApplication/ControlRoomApplication/Entities/SpectraCyber/SpectraCyberIntegrationTimeEnum.cs b/ControlRoomApplication/ControlRoomApplication/Entities/SpectraCyber/SpectraCyberIntegrationTimeEnum.cs
index 32add9c8..219298e3 100644
--- a/ControlRoomApplication/ControlRoomApplication/Entities/SpectraCyber/SpectraCyberIntegrationTimeEnum.cs
+++ b/ControlRoomApplication/ControlRoomApplication/Entities/SpectraCyber/SpectraCyberIntegrationTimeEnum.cs
@@ -26,5 +26,35 @@ public static char GetValue(this SpectraCyberIntegrationTimeEnum time)
throw new System.Exception("Unexpected SpectraCyberIntegrationTimeEnum type");
}
}
+
+ public static SpectraCyberIntegrationTimeEnum GetEnumFromValue(double val)
+ {
+ switch (val)
+ {
+ case 0.3:
+ return SpectraCyberIntegrationTimeEnum.SHORT_TIME_SPAN;
+ case 0.75:
+ return SpectraCyberIntegrationTimeEnum.MID_TIME_SPAN;
+ case 1:
+ return SpectraCyberIntegrationTimeEnum.LONG_TIME_SPAN;
+ default:
+ return SpectraCyberIntegrationTimeEnum.UNDEFINED;
+ }
+ }
+
+ public static double GetDoubleValue(this SpectraCyberIntegrationTimeEnum time)
+ {
+ switch (time)
+ {
+ case SpectraCyberIntegrationTimeEnum.SHORT_TIME_SPAN:
+ return 0.3;
+ case SpectraCyberIntegrationTimeEnum.MID_TIME_SPAN:
+ return 0.75;
+ case SpectraCyberIntegrationTimeEnum.LONG_TIME_SPAN:
+ return 1;
+ default:
+ return 0.3;
+ }
+ }
}
}
diff --git a/ControlRoomApplication/ControlRoomApplication/Entities/SpectraCyber/SpectraCyberModeTypeEnum.cs b/ControlRoomApplication/ControlRoomApplication/Entities/SpectraCyber/SpectraCyberModeTypeEnum.cs
index 7050c952..7549864a 100644
--- a/ControlRoomApplication/ControlRoomApplication/Entities/SpectraCyber/SpectraCyberModeTypeEnum.cs
+++ b/ControlRoomApplication/ControlRoomApplication/Entities/SpectraCyber/SpectraCyberModeTypeEnum.cs
@@ -6,6 +6,7 @@ public enum SpectraCyberModeTypeEnum
{
UNKNOWN,
CONTINUUM,
- SPECTRAL
+ SPECTRAL,
+ NONE
}
}
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/Entities/SpectraCyber/SpectraCyberScanSchedule.cs b/ControlRoomApplication/ControlRoomApplication/Entities/SpectraCyber/SpectraCyberScanSchedule.cs
index cf0a40e8..033944a8 100644
--- a/ControlRoomApplication/ControlRoomApplication/Entities/SpectraCyber/SpectraCyberScanSchedule.cs
+++ b/ControlRoomApplication/ControlRoomApplication/Entities/SpectraCyber/SpectraCyberScanSchedule.cs
@@ -4,8 +4,8 @@ namespace ControlRoomApplication.Entities
{
public class SpectraCyberScanSchedule
{
- private SpectraCyberScanScheduleMode Mode { get; set; }
- private double ScanDelayMS { get; set; }
+ public SpectraCyberScanScheduleMode Mode { get; set; }
+ public double ScanDelayMS { get; set; }
// If this is true, that means the scanning starts after ScanDelayMS time has passed
// Otherwise, an amount of time equal to ScanIntervalMS has to pass again, then it starts scanning
private bool StartScanAfterDelay { get; set; }
@@ -108,9 +108,12 @@ public bool PollReadiness()
switch (Mode)
{
case SpectraCyberScanScheduleMode.SINGLE_SCAN:
- case SpectraCyberScanScheduleMode.CONTINUOUS_SCAN:
return true;
-
+ case SpectraCyberScanScheduleMode.CONTINUOUS_SCAN:
+ if (totalMS >= ScanDelayMS)
+ return true;
+ else
+ return false;
case SpectraCyberScanScheduleMode.SCHEDULED_SCAN:
if (ScanDelayMS > 0)
{
diff --git a/ControlRoomApplication/ControlRoomApplication/Entities/User/NotificationTypeEnum.cs b/ControlRoomApplication/ControlRoomApplication/Entities/User/NotificationTypeEnum.cs
new file mode 100644
index 00000000..0b267039
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Entities/User/NotificationTypeEnum.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ControlRoomApplication.Entities
+{
+ public enum NotificationTypeEnum
+ {
+ EMAIL,
+ SMS,
+ ALL
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/Entities/User/User.cs b/ControlRoomApplication/ControlRoomApplication/Entities/User/User.cs
index 4b252b97..54b26095 100644
--- a/ControlRoomApplication/ControlRoomApplication/Entities/User/User.cs
+++ b/ControlRoomApplication/ControlRoomApplication/Entities/User/User.cs
@@ -5,7 +5,7 @@
using System.ComponentModel.DataAnnotations.Schema;
-namespace ControlRoomApplication.Entities.User
+namespace ControlRoomApplication.Entities
{
[Table("user")]
public class User
@@ -13,17 +13,87 @@ public class User
public User()
{
}
+
+ public User(string firstName, string lastName, string email, NotificationTypeEnum e)
+ {
+ first_name = firstName;
+ last_name = lastName;
+ _Notification_Type = e;
+ email_address = email;
+ }
+ public User(string firstName, string lastName, string email, NotificationTypeEnum e, UserRole ur)
+ {
+ first_name = firstName;
+ last_name = lastName;
+ _Notification_Type = e;
+ email_address = email;
+ UR = ur;
+ }
+
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
- [Column("id")]
public int Id { get; set; }
- [MaxLength(100)]
+ // not nullable
+ [Column("first_name")]
+ public string first_name { get; set; }
+
+ // not nullable
+ [Column("last_name")]
+ public string last_name { get; set; }
+
+ [Index("email_address", 1, IsUnique = true)]
+ public string email_address { get; set; }
+
+ ///
+ /// The getter/setter for the status asscociated with this Appointment.
+ /// This is the
+ ///
+ [NotMapped]
+ public NotificationTypeEnum _Notification_Type
+ {
+ get
+ {
+ return (NotificationTypeEnum)Enum.Parse(typeof(NotificationTypeEnum), notification_type);
+ }
+ set
+ {
+ this.notification_type = value.ToString();
+ }
+ }
+
+ private string backingtype { get; set; }
+
[Required]
- [Column("username")]
- public string Username { get; set; }
- // This establishes the User relationship to Appointments
- public virtual Collection Appointments { get; set; }
+ [Column("notification_type")]
+ public string notification_type
+ {
+ get
+ {
+ return this.backingtype;
+ }
+ set
+ {
+ if (value == null || Enum.IsDefined(typeof(NotificationTypeEnum), value))
+ {
+ this.backingtype = value;
+ }
+ else
+ {
+ throw new InvalidCastException();
+ }
+ }
+ }
+
+ [NotMapped]
+ public UserRole UR { get; set; }
+
+ [Column("phone_number")]
+ [StringLength(25)]
+ public string phone_number { get; set; }
+
+ [Column("firebase_id")]
+ public string firebase_id { get; set; }
}
}
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/Entities/User/UserRole.cs b/ControlRoomApplication/ControlRoomApplication/Entities/User/UserRole.cs
new file mode 100644
index 00000000..274c8484
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Entities/User/UserRole.cs
@@ -0,0 +1,62 @@
+using System;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+
+namespace ControlRoomApplication.Entities
+{
+
+ [Table("user_role")]
+ public class UserRole
+ {
+ [Key]
+ [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+ public int Id { get; set; }
+
+ // not nullable
+ [Column("user_id")]
+ public int user_id { get; set; }
+
+ [NotMapped]
+ public UserRoleEnum _User_Role
+ {
+ get
+ {
+ return (UserRoleEnum)Enum.Parse(typeof(UserRoleEnum), user_role);
+ }
+ set
+ {
+ this.user_role = value.ToString();
+ }
+ }
+
+ private string backingtype { get; set; }
+ [Required]
+ [Column("user_role")]
+ public string user_role
+ {
+ get
+ {
+ return this.backingtype;
+ }
+ set
+ {
+ if(value == null || Enum.IsDefined(typeof(UserRoleEnum), value))
+ {
+ this.backingtype = value;
+ }
+ else
+ {
+ throw new InvalidCastException();
+ }
+ }
+ }
+
+ public UserRole() { }
+
+ public UserRole(int uid, UserRoleEnum e)
+ {
+ user_id = uid;
+ _User_Role = e;
+ }
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/Entities/User/UserRoleEnum.cs b/ControlRoomApplication/ControlRoomApplication/Entities/User/UserRoleEnum.cs
new file mode 100644
index 00000000..3747418a
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Entities/User/UserRoleEnum.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ControlRoomApplication.Entities
+{
+ public enum UserRoleEnum
+ {
+ USER,
+ GUEST,
+ STUDENT,
+ RESEARCHER,
+ MEMBER,
+ ADMIN
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/Entities/WeatherStation/AbstractWeatherStation.cs b/ControlRoomApplication/ControlRoomApplication/Entities/WeatherStation/AbstractWeatherStation.cs
index 1867bf22..2ce2816b 100644
--- a/ControlRoomApplication/ControlRoomApplication/Entities/WeatherStation/AbstractWeatherStation.cs
+++ b/ControlRoomApplication/ControlRoomApplication/Entities/WeatherStation/AbstractWeatherStation.cs
@@ -1,6 +1,7 @@
using System;
using System.Threading;
using ControlRoomApplication.Constants;
+using ControlRoomApplication.Database;
namespace ControlRoomApplication.Entities
{
@@ -10,6 +11,9 @@ public abstract class AbstractWeatherStation : HeartbeatInterface
protected Thread OperatingThread;
protected bool KeepOperatingThreadAlive;
+ public Thread ReloadWeatherDataThread;
+ public bool KeepReloadWeatherDataThreadAlive;
+
private double _CurrentWindSpeedMPH;
public double CurrentWindSpeedMPH
@@ -17,13 +21,52 @@ public double CurrentWindSpeedMPH
get
{
OperatingMutex.WaitOne();
- double read = _CurrentWindSpeedMPH;
+ double read = GetWindSpeed();
OperatingMutex.ReleaseMutex();
return read;
}
}
+
+ public struct Weather_Data
+ {
+ public float windSpeed;
+ public String windDirection;
+ public float windDirectionDegrees;
+ public float dailyRain;
+ public float rainRate;
+ public float outsideTemp;
+ public float insideTemp;
+ public float baromPressure;
+ public float dewPoint;
+ public float windChill;
+ public float outsideHumidity;
+ public float totalRain;
+ public float monthlyRain;
+ public float heatIndex;
+
+ public Weather_Data(float windSpeedIN, String windDirectionIN, float windDirectionDegreesIN, float dailyRainIN, float rainRateIN,
+ float outsideTempIN, float insideTempIN, float baromPressureIN, float dewPointIN, float windChillIN,
+ float outsideHumidityIN, float totalRainIN, float monthlyRainIN, float heatIndexIN)
+ {
+ windSpeed = windSpeedIN;
+ windDirection = windDirectionIN;
+ windDirectionDegrees = windDirectionDegreesIN;
+ dailyRain = dailyRainIN;
+ rainRate = rainRateIN;
+ outsideTemp = outsideTempIN;
+ insideTemp = insideTempIN;
+ baromPressure = baromPressureIN;
+ dewPoint = dewPointIN;
+ windChill = windChillIN;
+ outsideHumidity = outsideHumidityIN;
+ totalRain = totalRainIN;
+ monthlyRain = monthlyRainIN;
+ heatIndex = heatIndexIN;
+ }
+ };
+
public int CurrentWindSpeedScanDelayMS { get; }
public bool CurrentWindSpeedIsAllowable
@@ -34,6 +77,22 @@ public bool CurrentWindSpeedIsAllowable
}
}
+ public int CurrentWindSpeedStatus
+ {
+ get
+ {
+ if (CurrentWindSpeedMPH < MiscellaneousHardwareConstants.WEATHER_STATION_WARNING_WIND_SPEED_MPH)
+ return 0; // Safe State of the Wind Speed
+ else if (CurrentWindSpeedMPH >= MiscellaneousHardwareConstants.WEATHER_STATION_WARNING_WIND_SPEED_MPH
+ && CurrentWindSpeedMPH <= DatabaseOperations.GetThresholdForSensor(SensorItemEnum.WIND))
+ return 1; // Warning State of the Wind Speed
+ else
+ return 2; // Alarm State of the Wind Speed
+ }
+ }
+
+
+
public AbstractWeatherStation(int currentWindSpeedScanDelayMS)
{
CurrentWindSpeedScanDelayMS = currentWindSpeedScanDelayMS;
@@ -41,7 +100,10 @@ public AbstractWeatherStation(int currentWindSpeedScanDelayMS)
OperatingMutex = new Mutex();
OperatingThread = new Thread(new ThreadStart(OperationLoop));
KeepOperatingThreadAlive = false;
- }
+
+ ReloadWeatherDataThread = null;
+ KeepReloadWeatherDataThreadAlive = false;
+ }
public bool Start()
{
@@ -75,12 +137,14 @@ public bool RequestKillAndJoin()
KeepOperatingThreadAlive = false;
OperatingMutex.ReleaseMutex();
+ KeepReloadWeatherDataThreadAlive = false;
+ ReloadWeatherDataThread.Join();
OperatingThread.Join();
}
catch (Exception e)
{
if ((e is ObjectDisposedException) || (e is AbandonedMutexException) || (e is InvalidOperationException)
- || (e is ApplicationException) || (e is ThreadStateException) | (e is ThreadInterruptedException))
+ || (e is ApplicationException) || (e is ThreadStateException) || (e is ThreadInterruptedException))
{
return false;
}
@@ -103,7 +167,7 @@ public void OperationLoop()
while (KeepAlive)
{
OperatingMutex.WaitOne();
- _CurrentWindSpeedMPH = ReadCurrentWindSpeedMPH();
+ _CurrentWindSpeedMPH = GetWindSpeed();
KeepAlive = KeepOperatingThreadAlive;
OperatingMutex.ReleaseMutex();
@@ -115,7 +179,23 @@ protected override bool KillHeartbeatComponent()
{
return RequestKillAndJoin();
}
-
- protected abstract double ReadCurrentWindSpeedMPH();
+
+ public abstract float GetBarometricPressure();
+ public abstract float GetOutsideTemp();
+ public abstract float GetInsideTemp();
+ public abstract float GetDewPoint();
+ public abstract float GetWindChill();
+ public abstract int GetHumidity();
+ public abstract float GetTotalRain();
+ public abstract float GetDailyRain();
+ public abstract float GetMonthlyRain();
+ public abstract float GetWindSpeed();
+ public abstract String GetWindDirection();
+ public abstract float GetRainRate();
+ public abstract int GetHeatIndex();
+
+ // An abstract method that will get all of the information
+ // to be able to put into the database cleanly
+ //protected abstract short GetAllRecords();
}
}
diff --git a/ControlRoomApplication/ControlRoomApplication/Entities/WeatherStation/WeatherData.cs b/ControlRoomApplication/ControlRoomApplication/Entities/WeatherStation/WeatherData.cs
new file mode 100644
index 00000000..1c083f40
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Entities/WeatherStation/WeatherData.cs
@@ -0,0 +1,106 @@
+using System;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+
+namespace ControlRoomApplication.Entities
+{
+ [Table("weather_data")]
+ public class WeatherData
+ {
+ public WeatherData()
+ {
+
+ }
+
+ [Key]
+ [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+ public int Id { get; set; }
+
+
+ [Required]
+ [Column("time_captured")]
+ public long TimeCaptured { get; set; }
+
+ [Required]
+ [Column("wind_speed")]
+ public Single ws { get; set; }
+
+ [Required]
+ [Column("wind_direction_deg")]
+ public Single wd_deg { get; set; }
+
+ [Required]
+ [Column("wind_direction_str")]
+ public String wd_str { get; set; }
+
+ [Required]
+ [Column("outside_temperature_degF")]
+ public Single ot { get; set; }
+
+ [Required]
+ [Column("inside_temperature_degF")]
+ public Single it { get; set; }
+
+ [Required]
+ [Column("rain_rate")]
+ public Single rr { get; set; }
+
+ [Required]
+ [Column("rain_total")]
+ public Single rt { get; set; }
+
+ [Required]
+ [Column("rain_day")]
+ public Single rd { get; set; }
+
+ [Required]
+ [Column("rain_month")]
+ public Single rm { get; set; }
+
+ [Required]
+ [Column("barometric_pressure")]
+ public Single bp { get; set; }
+
+ [Required]
+ [Column("dew_point")]
+ public Single dp { get; set; }
+
+ [Required]
+ [Column("wind_chill")]
+ public Single wc { get; set; }
+
+ [Required]
+ [Column("humidity")]
+ public Single hum { get; set; }
+
+ [Required]
+ [Column("heat_index")]
+ public Single heat { get; set; }
+
+
+
+ public static WeatherData Generate(AbstractWeatherStation.Weather_Data data)
+ {
+ WeatherData dbData = new WeatherData();
+
+ dbData.TimeCaptured = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
+ dbData.ws = data.windSpeed;
+ dbData.wd_str = data.windDirection;
+ dbData.wd_deg = data.windDirectionDegrees;
+ dbData.rd = data.dailyRain;
+ dbData.rr = data.rainRate;
+ dbData.ot = data.outsideTemp;
+ dbData.it = data.insideTemp;
+ dbData.bp = data.baromPressure;
+ dbData.dp = data.dewPoint;
+ dbData.wc = data.windChill;
+ dbData.hum = data.outsideHumidity;
+ dbData.rt = data.totalRain;
+ dbData.rm = data.monthlyRain;
+ dbData.heat = data.heatIndex;
+
+ return dbData;
+ }
+ }
+}
+
diff --git a/ControlRoomApplication/ControlRoomApplication/Entities/WeatherStation/WeatherStation.cs b/ControlRoomApplication/ControlRoomApplication/Entities/WeatherStation/WeatherStation.cs
new file mode 100644
index 00000000..624c1ec5
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Entities/WeatherStation/WeatherStation.cs
@@ -0,0 +1,283 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Threading;
+using System.Runtime.InteropServices;
+using ControlRoomApplication.Database;
+using ControlRoomApplication.Controllers.Sensors;
+using ControlRoomApplication.Util;
+using System.Data.Entity.Core;
+
+namespace ControlRoomApplication.Entities.WeatherStation
+{
+ public class WeatherStation : AbstractWeatherStation
+ {
+ private static readonly log4net.ILog logger =
+ log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
+
+ int count = 0;
+
+ public struct WeatherUnits
+ {
+ public char tempUnit;
+ public char RainUnit;
+ public char BaromUnit;
+ public char WindUnit;
+ public char elevUnit;
+ };
+
+ private String[] windDirections = { "N", "NNE", "NE", "ENE", "E", "ESE", "SE", "SSE", "S",
+ "SSW", "SW", "WSW", "W", "WNW", "NW", "NNW"};
+
+
+
+ // declarations of all methods we will use in the dll
+
+ //getters, get data from dll
+ [DllImport("VantageProDll242\\VantagePro.dll")] public static extern float GetWindSpeed_V();
+ [DllImport("VantageProDll242\\VantagePro.dll")] public static extern float GetBarometer_V();
+ [DllImport("VantageProDll242\\VantagePro.dll")] public static extern float GetOutsideTemp_V();
+ [DllImport("VantageProDll242\\VantagePro.dll")] public static extern float GetInsideTemp_V();
+ [DllImport("VantageProDll242\\VantagePro.dll")] public static extern float GetDewPt_V();
+ [DllImport("VantageProDll242\\VantagePro.dll")] public static extern float GetWindChill_V();
+ [DllImport("VantageProDll242\\VantagePro.dll")] public static extern short GetOutsideHumidity_V();
+ [DllImport("VantageProDll242\\VantagePro.dll")] public static extern float GetTotalRain_V();
+ [DllImport("VantageProDll242\\VantagePro.dll")] public static extern float GetDailyRain_V();
+ [DllImport("VantageProDll242\\VantagePro.dll")] public static extern float GetMonthlyRain_V();
+ [DllImport("VantageProDll242\\VantagePro.dll")] public static extern short GetWindDir_V();
+ [DllImport("VantageProDll242\\VantagePro.dll")] public static extern float GetRainRate_V();
+ [DllImport("VantageProDll242\\VantagePro.dll")] public static extern int GetHeatIndex_V();
+ [DllImport("VantageProDll242\\VantagePro.dll")] public static extern short GetModelNo_V();
+
+ //setup
+ [DllImport( "VantageProDll242\\VantagePro.dll" )] public static extern short OpenCommPort_V( short comPort , int baudRate );
+ [DllImport( "VantageProDll242\\VantagePro.dll" )] public static extern short InitStation_V();
+ [DllImport( "VantageProDll242\\VantagePro.dll" )] public static extern short OpenUSBPort_V();
+ [DllImport( "VantageProDll242\\VantagePro.dll" )] public static extern short SetUnits_V( WeatherUnits units );
+ [DllImport("VantageProDll242\\VantagePro.dll")] public static extern short SetVantageTimeoutVal_V(short TimeOutType);
+ [DllImport( "VantageProDll242\\VantagePro.dll" )] public static extern short SetCommTimeoutVal_V( short ReadTimeout , short WriteTimeout );
+
+ //loaders, call these to get from weather station into dll
+ [DllImport( "VantageProDll242\\VantagePro.dll" )] public static extern short LoadCurrentVantageData_V();
+ [DllImport( "VantageProDll242\\VantagePro.dll" )] public static extern int LoadVantageHiLows_V();
+ //public static extern short GetArchiveRecord_V(WeatherRecordStruct newRecord, short i);
+
+ private const int COM_ERROR = -32701;
+ private const int MEMORY_ERROR = -102;
+ private const int COM_OPEN_ERROR = -32701;
+ private const int NOT_LOADED_ERROR = -104;
+ private const int BAD_DATA = -32704;
+
+ Weather_Data data;
+
+ public WeatherStation(int currentWindSpeedScanDelayMS, int commPort = 3)
+ : base(currentWindSpeedScanDelayMS)
+ {
+
+ data = new Weather_Data(0, " ", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+
+ InitializeStation(commPort);
+
+ ReloadWeatherDataThread = new Thread(() => { ReloadWeatherDataRoutine(); });
+ KeepReloadWeatherDataThreadAlive = true;
+ ReloadWeatherDataThread.Start();
+ }
+
+ // From the HeartbeatInterface
+ public override bool TestIfComponentIsAlive()
+ {
+ // see if we can connect to the weather station
+ return GetModelNo_V() != COM_ERROR;
+ }
+
+ ///
+ /// Sets up connection with the production weather station.
+ /// If loading the data fails, its no big deal. We are going to attempt to load the data every time
+ /// a getter method is called.
+ ///
+ /// void
+ protected void InitializeStation(int commPort)
+ {
+ if (OpenCommPort_V((short)commPort, 19200) != 0)
+ {
+ logger.Error(Utilities.GetTimeStamp() + ": OpenCommPort unsuccessful!");
+ throw new ExternalException();
+ }
+
+ if (InitStation_V() == COM_ERROR)
+ {
+ logger.Error(Utilities.GetTimeStamp() + ": Initialize Station unsuccessful!");
+ throw new ExternalException();
+ }
+
+ // if(LoadCurrentVantageData_V() == COM_ERROR || LoadVantageHiLows_V() == COM_ERROR) {
+ // logger.Info( "failed to collect data from weather station. will attempt again." );
+ // }
+
+ logger.Info(Utilities.GetTimeStamp() + ": Initialize Concrete Weather Station successful!");
+ }
+
+ private void ReloadWeatherDataRoutine()
+ {
+ bool retrySave = false;
+
+ while (KeepReloadWeatherDataThreadAlive) {
+ if (LoadCurrentVantageData_V() != COM_ERROR)
+ {
+ data.windSpeed = GetWindSpeed_V();
+ data.windDirectionDegrees = GetWindDir_V();
+ data.windDirection = ConvertWindDirDegreesToStr(data.windDirectionDegrees);
+ data.dailyRain = GetDailyRain_V();
+ data.rainRate = GetRainRate_V();
+ data.outsideTemp = GetOutsideTemp_V();
+ data.insideTemp = GetInsideTemp_V();
+ data.baromPressure = GetBarometer_V();
+ data.dewPoint = GetDewPt_V();
+ data.windChill = GetWindChill_V();
+ data.outsideHumidity = GetOutsideHumidity_V();
+ data.totalRain = GetTotalRain_V();
+ data.monthlyRain = GetMonthlyRain_V();
+ data.heatIndex = GetHeatIndex_V();
+
+ // This is here for a workaround to issue #360. We will occasionally get a "Connection failed on open" Entity exception
+ // We have this used to simply retry the database update if the exception occurs. It always (while I was testing, at least) succeeds after the retry.
+ // We may need to remove this in production if we find a different solution for actually eliminating the bug insetad of this workaround
+
+ do
+ {
+ try
+ {
+ DatabaseOperations.AddWeatherData(WeatherData.Generate(data));
+ retrySave = false;
+ count = 0;
+ }
+ catch (EntityException e)
+ {
+ count++;
+ retrySave = true;
+
+ // We want to retry 4 times, after which we will abandon the update.
+ if (count == 4)
+ {
+ retrySave = false;
+ count = 0;
+ logger.Info(Utilities.GetTimeStamp() + " : Failed to update weather station data after 4 tries. Abandoning update...");
+ }
+ }
+ }
+ while (retrySave);
+ }
+
+
+ Thread.Sleep(1000);
+ }
+ }
+
+ public bool RequestToKillReloadWeatherDataRoutine()
+ {
+ KeepReloadWeatherDataThreadAlive = false;
+
+ try
+ {
+ ReloadWeatherDataThread.Join();
+ }
+ catch (Exception e)
+ {
+ if ((e is ThreadStateException) || (e is ThreadInterruptedException))
+ {
+ return false;
+ }
+ else
+ {
+ // Unexpected exception
+ throw e;
+ }
+ }
+
+ return true;
+ }
+
+ public override float GetWindSpeed()
+ {
+ return data.windSpeed;
+ }
+
+ public override float GetBarometricPressure()
+ {
+ return data.baromPressure;
+ }
+
+ public override float GetOutsideTemp()
+ {
+ return data.outsideTemp;
+ }
+
+ public override float GetInsideTemp()
+ {
+ return data.insideTemp;
+ }
+
+ public override float GetDewPoint()
+ {
+ return data.dewPoint;
+ }
+
+ public override float GetWindChill()
+ {
+ return data.windChill;
+ }
+
+ public override int GetHumidity()
+ {
+ return (int)data.outsideHumidity;
+ }
+
+ public override float GetTotalRain()
+ {
+ return data.totalRain;
+ }
+
+ public override float GetDailyRain()
+ {
+ return data.dailyRain;
+ }
+
+ public override float GetMonthlyRain()
+ {
+ return data.monthlyRain;
+ }
+
+ public override String GetWindDirection()
+ {
+ return data.windDirection;
+ }
+
+ public override float GetRainRate()
+ {
+ return data.rainRate;
+ }
+
+ public override int GetHeatIndex()
+ {
+ return (int)data.heatIndex;
+ }
+
+ private string ConvertWindDirDegreesToStr(float degrees)
+ {
+ double leftBoundary = 348.75;
+ double rightBoundary = 11.25;
+
+ for(int i = 0; i < windDirections.Length ; i++)
+ {
+ if (degrees > (leftBoundary+(22.5*i)) % 360 && degrees < rightBoundary+(22.5 * i))
+ {
+ return windDirections[i - 1];
+ }
+ }
+
+ return "ERR";
+ }
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/Entities/WeatherStation/WeatherThreshold.cs b/ControlRoomApplication/ControlRoomApplication/Entities/WeatherStation/WeatherThreshold.cs
new file mode 100644
index 00000000..e64167b1
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Entities/WeatherStation/WeatherThreshold.cs
@@ -0,0 +1,34 @@
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+
+namespace ControlRoomApplication.Entities
+{
+ [Table("weather_threshold")]
+ public class WeatherThreshold
+ {
+
+ public WeatherThreshold(int windSpeed, int snowDumpTime)
+ {
+ WindSpeed = windSpeed;
+ SnowDumpTime = snowDumpTime;
+ }
+
+ public WeatherThreshold()
+ {
+
+ }
+
+ [Key]
+ [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+ public int Id { get; set; }
+
+
+ [Column("wind_speed")]
+ public int WindSpeed { get; set; }
+
+ [Column("snow_dump_time")]
+ public int SnowDumpTime { get; set; }
+
+
+ }
+}
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/External_Controlers/BulkHead-Uprosesor/acceleromitor_test.js b/ControlRoomApplication/ControlRoomApplication/External_Controlers/BulkHead-Uprosesor/acceleromitor_test.js
new file mode 100644
index 00000000..051adb03
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/External_Controlers/BulkHead-Uprosesor/acceleromitor_test.js
@@ -0,0 +1,95 @@
+const i2c = require('i2c-bus');
+
+const DS1621_ADDR = 0x53;
+const CMD_ACCESS_CONFIG = 0xac;
+const CMD_READ_TEMP = 0xA7;
+const CMD_START_CONVERT = 0xee;
+const ADXL345_POWER_CTL = 0x2D;
+const toCelsius = (rawTemp) => {
+ const halfDegrees = ((rawTemp & 0xff) << 1) + (rawTemp >> 15);
+
+ if ((halfDegrees & 0x100) === 0) {
+ return halfDegrees / 2; // Temp +ve
+ }
+
+ return -((~halfDegrees & 0xff) / 2); // Temp -ve
+};
+
+const displayTemperature = () => {
+ const i2c1 = i2c.openSync(1);
+ console.log(i2c1);
+ // Enter one shot mode (this is a non volatile setting)
+ //i2c1.writeByteSync(DS1621_ADDR, CMD_ACCESS_CONFIG, 0x01);
+ console.log(i2c1.readByteSync(DS1621_ADDR, CMD_ACCESS_CONFIG))
+ // Wait while non volatile memory busy
+ while (i2c1.readByteSync(DS1621_ADDR, CMD_ACCESS_CONFIG) & 0x10) {
+ }
+
+ // Start temperature conversion
+ i2c1.sendByteSync(DS1621_ADDR, CMD_START_CONVERT);
+
+ // Wait for temperature conversion to complete
+ while ((i2c1.readByteSync(DS1621_ADDR, CMD_ACCESS_CONFIG) & 0x80) === 0) {
+ }
+
+ // Display temperature
+ const rawTemp = i2c1.readWordSync(DS1621_ADDR, CMD_READ_TEMP);
+ console.log('temp: ' + toCelsius(rawTemp));
+
+ i2c1.closeSync();
+};
+
+function sleep(ms) {
+ return new Promise(resolve => setTimeout(resolve, ms));
+}
+
+//displayTemperature();
+let completed=0;
+async function run() {
+ const i2c1 = i2c.openSync(2);
+ console.log("start");
+ i2c1.writeByteSync(DS1621_ADDR, ADXL345_POWER_CTL, 0);
+ i2c1.writeByteSync(DS1621_ADDR, ADXL345_POWER_CTL, 16);
+ i2c1.writeByteSync(DS1621_ADDR, ADXL345_POWER_CTL, 8);
+ console.log("configd");
+ console.time();
+ for(var i=0;i<50;i++) {
+ for(var j=0;j<20;j++) {
+ let data = Buffer.alloc(6);
+ i2c1.readI2cBlock(DS1621_ADDR, 0x32, 6, data, I2CCallbac);
+ }
+ /*
+ try {
+ //Buffer[] data;//[6];// =new Buffer[6];
+ let data = Buffer.alloc(6);
+ i2c1.readI2cBlockSync(DS1621_ADDR, 0x32, 6, data);
+ // console.log(data[1].toString(2).padStart(8, '0')+""+data[0].toString(2).padStart(8, '0')+" "+data[3].toString(2).padStart(8, '0')+""+data[2].toString(2).padStart(8, '0')+" "+data[5].toString(2).padStart(8, '0')+""+data[4].toString(2).padStart(8, '0') );
+ let x = Twos_compliment_16(data[1], data[0]);
+ let y = Twos_compliment_16(data[3], data[2]);
+ let z = Twos_compliment_16(data[5], data[4]);
+ //console.log(` ${x/256} ${y/256} ${z/256}`);
+ } catch (err) {
+ console.log(err);
+ await sleep(200);
+ }
+ */
+ }
+}
+
+run();
+
+function I2CCallbac (error, bytesRead, buffer){
+ completed++;
+ if (completed==1000){
+ console.timeEnd()
+ }
+}
+
+function Twos_compliment_16(msw, lsw) {
+ let unsignedValue = (msw << 8) + (lsw);
+ if ((unsignedValue & 0x8000)) {
+ return (unsignedValue | 0xffff0000);
+ } else {
+ return unsignedValue;
+ }
+}
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/External_Controlers/BulkHead-Uprosesor/main.js b/ControlRoomApplication/ControlRoomApplication/External_Controlers/BulkHead-Uprosesor/main.js
index 2960a254..1c67d91f 100644
--- a/ControlRoomApplication/ControlRoomApplication/External_Controlers/BulkHead-Uprosesor/main.js
+++ b/ControlRoomApplication/ControlRoomApplication/External_Controlers/BulkHead-Uprosesor/main.js
@@ -57,15 +57,12 @@ function startup() {
});
} catch (err) { console.log(err); client.destroy(); startup(); }
}
-/*
-var fs = require('fs');
-var out = fs.openSync('./out.log', 'a');
-var err = fs.openSync('./out.log', 'a');
-*/
+
+/* spawn child process to colect position data on seprate process
var cp = require('child_process');
var child = cp.spawn('node', ['server.js'], { detached: true, stdio: ['ignore'] });
child.unref();
-
+*/
startup();
function cleanup() {
diff --git a/ControlRoomApplication/ControlRoomApplication/External_Controlers/Ip-Camera-Recorder.py b/ControlRoomApplication/ControlRoomApplication/External_Controlers/Ip-Camera-Recorder.py
new file mode 100644
index 00000000..42134fe5
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/External_Controlers/Ip-Camera-Recorder.py
@@ -0,0 +1,84 @@
+hires = True
+camIP ="169.254.113.233"
+
+
+
+
+
+import numpy as np
+import cv2
+import time
+import imutils
+
+width = 1920
+height = 1080
+start = time.time()
+streamId=1
+if hires:
+ streamId=0
+cap = cv2.VideoCapture('rtsp://'+camIP+':554/user=admin_password=6QNMIQGe_channel=0_stream='+str(streamId)+'.sdp/trackID=4')
+fourcc = cv2.VideoWriter_fourcc(*'XVID')
+#out = cv2.VideoWriter('output.avi', fourcc, 20.0, (704,480))
+out = cv2.VideoWriter('output.avi', fourcc, 20.0, (width,height))
+
+ret, frame = cap.read()
+end = time.time()
+print("time to aquire capture "+str(end - start))
+
+cv2.imshow('image',frame)
+ret, firstFrame = cap.read()
+
+firstFrame = cv2.cvtColor(firstFrame, cv2.COLOR_BGR2GRAY)
+firstFrame = cv2.GaussianBlur(firstFrame, (21, 21), 0)
+
+height1, width1 = frame.shape[:2]
+if (height1 != height) or (width1 != width):
+ height = height1
+ width = width1
+ out = cv2.VideoWriter('output.avi', fourcc, 20.0, (width,height))
+
+
+
+frameCount =0
+while(True):
+ frameCount+=1
+ ret, frame = cap.read()
+ #cv2.imshow('frame',frame)
+ #imshow( "Display window", image ); # Show our image inside it.
+ gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
+ gray = cv2.GaussianBlur(gray, (21, 21), 0)
+ frameDelta = cv2.absdiff(firstFrame, gray)
+ thresh = cv2.threshold(frameDelta, 25, 255, cv2.THRESH_BINARY)[1]
+
+
+ thresh = cv2.dilate(thresh, None, iterations=2)
+ cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,
+ cv2.CHAIN_APPROX_SIMPLE)
+ cnts = imutils.grab_contours(cnts)
+
+
+ for c in cnts:
+ # if the contour is too small, ignore it
+ if cv2.contourArea(c) < 200:
+ continue
+
+ # compute the bounding box for the contour, draw it on the frame,
+ # and update the text
+ (x, y, w, h) = cv2.boundingRect(c)
+ cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
+
+
+ out.write(frame)
+ cv2.imshow('image',frame)
+
+ if frameCount > 500:
+ break
+ if cv2.waitKey(1) & 0xFF == ord('q'):
+ break
+
+cap.release()
+out.release()
+cv2.destroyAllWindows()
+
+print("fin")
+
diff --git a/ControlRoomApplication/ControlRoomApplication/External_Controlers/scalePLCArdrionCode/RTCode.ino b/ControlRoomApplication/ControlRoomApplication/External_Controlers/scalePLCArdrionCode/RTCode.ino
new file mode 100644
index 00000000..9db3e546
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/External_Controlers/scalePLCArdrionCode/RTCode.ino
@@ -0,0 +1,52 @@
+
+
+String incoming = ""; // for incoming serial string data
+int incomingByte = 0;
+void setup() {
+ Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
+}
+
+void loop() {
+ // send data only when you receive data:
+ /*
+ if (Serial.available() > 0) {
+ // read the incoming:
+ incoming = Serial.readString();
+ // say what you got:
+ Serial.println(incoming);
+ if (incoming == 'demo') {
+ //demo routine
+ Serial.println("you started the demo routine");
+ }
+ else if (incoming=='sort') {
+ //sorteer routine
+ Serial.println("you started the sort routine");
+ }
+ else {
+ //junk
+ Serial.println("something else");
+ incoming = "";
+ }
+ Serial.flush();
+ }
+ */
+ if (Serial.available() > 0) {
+ int v=0;
+ char byteArray[1000];
+ for( int i = 0; i < sizeof(byteArray); ++i )
+ byteArray[i] = (char)0;
+ //strcpy((char *)byteArray,"0123");
+
+ while(true){
+ incomingByte = Serial.read();
+ if(incomingByte==-1||incomingByte==10){break;}
+ byteArray[v]= incomingByte;
+ v++;
+ }
+ String myString = String(byteArray);
+ Serial.println(myString);
+
+ // read the incoming byte:
+
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/GUI/DiagnosticsForm.Designer.cs b/ControlRoomApplication/ControlRoomApplication/GUI/DiagnosticsForm.Designer.cs
index 8b436263..76f87a5d 100644
--- a/ControlRoomApplication/ControlRoomApplication/GUI/DiagnosticsForm.Designer.cs
+++ b/ControlRoomApplication/ControlRoomApplication/GUI/DiagnosticsForm.Designer.cs
@@ -30,12 +30,27 @@ private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle();
+ System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea1 = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
+ System.Windows.Forms.DataVisualization.Charting.Series series1 = new System.Windows.Forms.DataVisualization.Charting.Series();
+ System.Windows.Forms.DataVisualization.Charting.Series series2 = new System.Windows.Forms.DataVisualization.Charting.Series();
+ System.Windows.Forms.DataVisualization.Charting.Series series3 = new System.Windows.Forms.DataVisualization.Charting.Series();
+ System.Windows.Forms.DataVisualization.Charting.Series series4 = new System.Windows.Forms.DataVisualization.Charting.Series();
+ System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea2 = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
+ System.Windows.Forms.DataVisualization.Charting.Series series5 = new System.Windows.Forms.DataVisualization.Charting.Series();
+ System.Windows.Forms.DataVisualization.Charting.Series series6 = new System.Windows.Forms.DataVisualization.Charting.Series();
+ System.Windows.Forms.DataVisualization.Charting.Series series7 = new System.Windows.Forms.DataVisualization.Charting.Series();
+ System.Windows.Forms.DataVisualization.Charting.Series series8 = new System.Windows.Forms.DataVisualization.Charting.Series();
+ System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea3 = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
+ System.Windows.Forms.DataVisualization.Charting.Series series9 = new System.Windows.Forms.DataVisualization.Charting.Series();
+ System.Windows.Forms.DataVisualization.Charting.Series series10 = new System.Windows.Forms.DataVisualization.Charting.Series();
+ System.Windows.Forms.DataVisualization.Charting.Series series11 = new System.Windows.Forms.DataVisualization.Charting.Series();
+ System.Windows.Forms.DataVisualization.Charting.Series series12 = new System.Windows.Forms.DataVisualization.Charting.Series();
+ System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea4 = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
+ System.Windows.Forms.DataVisualization.Charting.Legend legend1 = new System.Windows.Forms.DataVisualization.Charting.Legend();
+ System.Windows.Forms.DataVisualization.Charting.Series series13 = new System.Windows.Forms.DataVisualization.Charting.Series();
this.dataGridView1 = new System.Windows.Forms.DataGridView();
- this.lblCurrentAzOrientation = new System.Windows.Forms.Label();
- this.lblCurrentElOrientation = new System.Windows.Forms.Label();
- this.label3 = new System.Windows.Forms.Label();
- this.label4 = new System.Windows.Forms.Label();
- this.label5 = new System.Windows.Forms.Label();
+ this.windSpeedLabel = new System.Windows.Forms.Label();
+ this.windDirLabel = new System.Windows.Forms.Label();
this.label6 = new System.Windows.Forms.Label();
this.label7 = new System.Windows.Forms.Label();
this.startTimeTextBox = new System.Windows.Forms.TextBox();
@@ -45,43 +60,10 @@ private void InitializeComponent()
this.timer1 = new System.Windows.Forms.Timer(this.components);
this.lblAzimuthTemp = new System.Windows.Forms.Label();
this.lblElevationTemp = new System.Windows.Forms.Label();
- this.radioButton1 = new System.Windows.Forms.RadioButton();
- this.radioButton2 = new System.Windows.Forms.RadioButton();
this.fldAzTemp = new System.Windows.Forms.Label();
this.fldElTemp = new System.Windows.Forms.Label();
- this.txtTemperature = new System.Windows.Forms.TextBox();
this.btnTest = new System.Windows.Forms.Button();
- this.warningLabel = new System.Windows.Forms.Label();
- this.fanLabel = new System.Windows.Forms.Label();
- this.btnAddOneTemp = new System.Windows.Forms.Button();
- this.btnAddFiveTemp = new System.Windows.Forms.Button();
- this.btnAddXTemp = new System.Windows.Forms.Button();
- this.lblShutdown = new System.Windows.Forms.Label();
this.selectDemo = new System.Windows.Forms.CheckBox();
- this.btnSubtractOneTemp = new System.Windows.Forms.Button();
- this.btnSubtractFiveTemp = new System.Windows.Forms.Button();
- this.btnSubtractXTemp = new System.Windows.Forms.Button();
- this.txtCustTemp = new System.Windows.Forms.TextBox();
- this.label11 = new System.Windows.Forms.Label();
- this.panel1 = new System.Windows.Forms.Panel();
- this.lblElLimStatus2 = new System.Windows.Forms.Label();
- this.lblElLimStatus1 = new System.Windows.Forms.Label();
- this.lblAzLimStatus2 = new System.Windows.Forms.Label();
- this.lblAzLimStatus1 = new System.Windows.Forms.Label();
- this.lblElLimit2 = new System.Windows.Forms.Label();
- this.lblElLimit1 = new System.Windows.Forms.Label();
- this.lblAzLimit2 = new System.Windows.Forms.Label();
- this.lblAzLimit1 = new System.Windows.Forms.Label();
- this.lblEleProx2 = new System.Windows.Forms.Label();
- this.lblEleProx1 = new System.Windows.Forms.Label();
- this.lblElProx2 = new System.Windows.Forms.Label();
- this.lblElProx1 = new System.Windows.Forms.Label();
- this.lblAzProxStatus3 = new System.Windows.Forms.Label();
- this.lblAzProxStatus2 = new System.Windows.Forms.Label();
- this.lblAzProxStatus1 = new System.Windows.Forms.Label();
- this.lblAzProx3 = new System.Windows.Forms.Label();
- this.lblAzProx2 = new System.Windows.Forms.Label();
- this.lblAzProx1 = new System.Windows.Forms.Label();
this.lblAbsEncoder = new System.Windows.Forms.Label();
this.lblEncoderDegrees = new System.Windows.Forms.Label();
this.lblAzEncoderDegrees = new System.Windows.Forms.Label();
@@ -115,11 +97,202 @@ private void InitializeComponent()
this.textBox3 = new System.Windows.Forms.TextBox();
this.textBox4 = new System.Windows.Forms.TextBox();
this.label18 = new System.Windows.Forms.Label();
+ this.tabControl1 = new System.Windows.Forms.TabControl();
+ this.tabPage1 = new System.Windows.Forms.TabPage();
+ this.button7 = new System.Windows.Forms.Button();
+ this.groupBox9 = new System.Windows.Forms.GroupBox();
+ this.groupBox8 = new System.Windows.Forms.GroupBox();
+ this.runDiagScriptsButton = new System.Windows.Forms.Button();
+ this.diagnosticScriptCombo = new System.Windows.Forms.ComboBox();
+ this.groupBox3 = new System.Windows.Forms.GroupBox();
+ this.groupBox2 = new System.Windows.Forms.GroupBox();
+ this.splitContainer2 = new System.Windows.Forms.SplitContainer();
+ this.groupBox1 = new System.Windows.Forms.GroupBox();
+ this.tabPage2 = new System.Windows.Forms.TabPage();
+ this.grpAccelerometerSensorData = new System.Windows.Forms.GroupBox();
+ this.label26 = new System.Windows.Forms.Label();
+ this.label25 = new System.Windows.Forms.Label();
+ this.label45 = new System.Windows.Forms.Label();
+ this.label38 = new System.Windows.Forms.Label();
+ this.label46 = new System.Windows.Forms.Label();
+ this.label48 = new System.Windows.Forms.Label();
+ this.pnlCounterbalanceAccelerometer = new System.Windows.Forms.Panel();
+ this.lblCbDisabled = new System.Windows.Forms.Label();
+ this.counterBalanceAccChart = new System.Windows.Forms.DataVisualization.Charting.Chart();
+ this.label50 = new System.Windows.Forms.Label();
+ this.label37 = new System.Windows.Forms.Label();
+ this.label49 = new System.Windows.Forms.Label();
+ this.pnlElevationMotorAccelerometer = new System.Windows.Forms.Panel();
+ this.lblElDisabled = new System.Windows.Forms.Label();
+ this.elevationAccChart = new System.Windows.Forms.DataVisualization.Charting.Chart();
+ this.label47 = new System.Windows.Forms.Label();
+ this.label36 = new System.Windows.Forms.Label();
+ this.pnlAzimuthMotorAccelerometer = new System.Windows.Forms.Panel();
+ this.lblAzDisabled = new System.Windows.Forms.Label();
+ this.azimuthAccChart = new System.Windows.Forms.DataVisualization.Charting.Chart();
+ this.grpSensorData = new System.Windows.Forms.GroupBox();
+ this.lbGateStat = new System.Windows.Forms.Label();
+ this.lbEstopStat = new System.Windows.Forms.Label();
+ this.label31 = new System.Windows.Forms.Label();
+ this.label30 = new System.Windows.Forms.Label();
+ this.lblAzHome1 = new System.Windows.Forms.Label();
+ this.lblElLimStatus2 = new System.Windows.Forms.Label();
+ this.lblElLimStatus1 = new System.Windows.Forms.Label();
+ this.lblElHome = new System.Windows.Forms.Label();
+ this.lblELHomeStatus = new System.Windows.Forms.Label();
+ this.lblAzHomeStatus1 = new System.Windows.Forms.Label();
+ this.lblAzLimit1 = new System.Windows.Forms.Label();
+ this.lblAzLimit2 = new System.Windows.Forms.Label();
+ this.grpMcuStatus = new System.Windows.Forms.GroupBox();
+ this.lblMCUStatus = new System.Windows.Forms.Label();
+ this.lblMCUStatusText = new System.Windows.Forms.Label();
+ this.lblMCUErrors = new System.Windows.Forms.Label();
+ this.btnResetMcuErrors = new System.Windows.Forms.Button();
+ this.groupBox14 = new System.Windows.Forms.GroupBox();
+ this.farTempConvert = new System.Windows.Forms.Button();
+ this.celTempConvert = new System.Windows.Forms.Button();
+ this.grpAbsoluteMotorPositionsTemperatures = new System.Windows.Forms.GroupBox();
+ this.splitContainer1 = new System.Windows.Forms.SplitContainer();
+ this.label32 = new System.Windows.Forms.Label();
+ this.label34 = new System.Windows.Forms.Label();
+ this.lblCurrentAzOrientation = new System.Windows.Forms.Label();
+ this.lblCurrentElOrientation = new System.Windows.Forms.Label();
+ this.lblElAbsPos = new System.Windows.Forms.Label();
+ this.lblAzAbsPos = new System.Windows.Forms.Label();
+ this.AZTempUnitLabel = new System.Windows.Forms.Label();
+ this.ElTempUnitLabel = new System.Windows.Forms.Label();
+ this.groupBox5 = new System.Windows.Forms.GroupBox();
+ this.InsideTempUnits = new System.Windows.Forms.Label();
+ this.rainRateUnits = new System.Windows.Forms.Label();
+ this.pressUnits = new System.Windows.Forms.Label();
+ this.dailyRainfallUnits = new System.Windows.Forms.Label();
+ this.outTempUnits = new System.Windows.Forms.Label();
+ this.label35 = new System.Windows.Forms.Label();
+ this.windSpeedUnits = new System.Windows.Forms.Label();
+ this.insideTempLabel = new System.Windows.Forms.Label();
+ this.label23 = new System.Windows.Forms.Label();
+ this.rainRateLabel = new System.Windows.Forms.Label();
+ this.barometricPressureLabel = new System.Windows.Forms.Label();
+ this.dailyRainfallLabel = new System.Windows.Forms.Label();
+ this.outsideTempLabel = new System.Windows.Forms.Label();
this.label19 = new System.Windows.Forms.Label();
+ this.label20 = new System.Windows.Forms.Label();
+ this.label1 = new System.Windows.Forms.Label();
+ this.label2 = new System.Windows.Forms.Label();
+ this.label5 = new System.Windows.Forms.Label();
+ this.label11 = new System.Windows.Forms.Label();
+ this.tabPage3 = new System.Windows.Forms.TabPage();
+ this.Encoders = new System.Windows.Forms.GroupBox();
+ this.ElecationAbsoluteEncoder_lbl = new System.Windows.Forms.Label();
+ this.btnElevationAbsoluteEncoder = new System.Windows.Forms.Button();
+ this.btnAzimuthAbsoluteEncoder = new System.Windows.Forms.Button();
+ this.AzimuthAbsoluteEncoder_lbl = new System.Windows.Forms.Label();
+ this.SensorNetworkSensorInitialization = new System.Windows.Forms.GroupBox();
+ this.lblInitTimeout = new System.Windows.Forms.Label();
+ this.lblDataTimeout = new System.Windows.Forms.Label();
+ this.txtDataTimeout = new System.Windows.Forms.TextBox();
+ this.txtInitTimeout = new System.Windows.Forms.TextBox();
+ this.lblSNStatus = new System.Windows.Forms.Label();
+ this.UpdateSensorInitiliazation = new System.Windows.Forms.Button();
+ this.AzimuthEncoder = new System.Windows.Forms.CheckBox();
+ this.ElevationEncoder = new System.Windows.Forms.CheckBox();
+ this.CounterbalanceAccelerometer = new System.Windows.Forms.CheckBox();
+ this.ElevationAccelerometer = new System.Windows.Forms.CheckBox();
+ this.AzimuthAccelerometer = new System.Windows.Forms.CheckBox();
+ this.AzimuthTemperature1 = new System.Windows.Forms.CheckBox();
+ this.ElevationTemperature1 = new System.Windows.Forms.CheckBox();
+ this.SoftwareStopsThresholdGroup = new System.Windows.Forms.GroupBox();
+ this.SWStopLowerLabel = new System.Windows.Forms.Label();
+ this.SWStopUpperLabel = new System.Windows.Forms.Label();
+ this.UpdateSWStopsButton = new System.Windows.Forms.Button();
+ this.LowerSWStopsLimitText = new System.Windows.Forms.TextBox();
+ this.UpperSWStopsLimitText = new System.Windows.Forms.TextBox();
+ this.grpProximitySensors = new System.Windows.Forms.GroupBox();
+ this.label4 = new System.Windows.Forms.Label();
this.label21 = new System.Windows.Forms.Label();
+ this.ElivationLimitSwitch0 = new System.Windows.Forms.Button();
+ this.ElevationLimitSwitch90 = new System.Windows.Forms.Button();
+ this.MotorTemperatureSensors = new System.Windows.Forms.GroupBox();
+ this.ElMotTempSensOverride = new System.Windows.Forms.Button();
+ this.label29 = new System.Windows.Forms.Label();
+ this.AzMotTempSensOverride = new System.Windows.Forms.Button();
+ this.label28 = new System.Windows.Forms.Label();
+ this.GatesSensors = new System.Windows.Forms.GroupBox();
+ this.MGOverride = new System.Windows.Forms.Button();
+ this.label27 = new System.Windows.Forms.Label();
+ this.Accelerometers = new System.Windows.Forms.GroupBox();
+ this.btnElevationMotorAccelerometerOverride = new System.Windows.Forms.Button();
+ this.btnCounterbalanceMotorAccelerometerOverride = new System.Windows.Forms.Button();
+ this.btnAzimuthMotorAccelerometerOverride = new System.Windows.Forms.Button();
+ this.label33 = new System.Windows.Forms.Label();
+ this.label3 = new System.Windows.Forms.Label();
this.label22 = new System.Windows.Forms.Label();
+ this.WeatherStation = new System.Windows.Forms.GroupBox();
+ this.WSOverride = new System.Windows.Forms.Button();
+ this.label24 = new System.Windows.Forms.Label();
+ this.tabPage4 = new System.Windows.Forms.TabPage();
+ this.lblModeType = new System.Windows.Forms.Label();
+ this.spectraModeTypeVal = new System.Windows.Forms.Label();
+ this.lblFrequency = new System.Windows.Forms.Label();
+ this.frequencyVal = new System.Windows.Forms.Label();
+ this.spectraCyberScanChart = new System.Windows.Forms.DataVisualization.Charting.Chart();
+ this.lblIntegrationStep = new System.Windows.Forms.Label();
+ this.IntegrationStepVal = new System.Windows.Forms.Label();
+ this.lblDCGain = new System.Windows.Forms.Label();
+ this.DCGainVal = new System.Windows.Forms.Label();
+ this.lblIFGain = new System.Windows.Forms.Label();
+ this.IFGainVal = new System.Windows.Forms.Label();
+ this.lblBandwidth = new System.Windows.Forms.Label();
+ this.BandwidthVal = new System.Windows.Forms.Label();
+ this.lblOffsetVoltage = new System.Windows.Forms.Label();
+ this.OffsetVoltageVal = new System.Windows.Forms.Label();
+ this.tabPage5 = new System.Windows.Forms.TabPage();
+ this.consoleLogBox = new System.Windows.Forms.TextBox();
+ this.DataTimeoutValidation = new System.Windows.Forms.ToolTip(this.components);
+ this.InitTimeoutValidation = new System.Windows.Forms.ToolTip(this.components);
+ this.UpperLimitToolTip = new System.Windows.Forms.ToolTip(this.components);
+ this.LowerLimitToolTip = new System.Windows.Forms.ToolTip(this.components);
((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit();
- this.panel1.SuspendLayout();
+ this.tabControl1.SuspendLayout();
+ this.tabPage1.SuspendLayout();
+ this.groupBox9.SuspendLayout();
+ this.groupBox8.SuspendLayout();
+ this.groupBox3.SuspendLayout();
+ this.groupBox2.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.splitContainer2)).BeginInit();
+ this.splitContainer2.Panel1.SuspendLayout();
+ this.splitContainer2.Panel2.SuspendLayout();
+ this.splitContainer2.SuspendLayout();
+ this.groupBox1.SuspendLayout();
+ this.tabPage2.SuspendLayout();
+ this.grpAccelerometerSensorData.SuspendLayout();
+ this.pnlCounterbalanceAccelerometer.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.counterBalanceAccChart)).BeginInit();
+ this.pnlElevationMotorAccelerometer.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.elevationAccChart)).BeginInit();
+ this.pnlAzimuthMotorAccelerometer.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.azimuthAccChart)).BeginInit();
+ this.grpSensorData.SuspendLayout();
+ this.grpMcuStatus.SuspendLayout();
+ this.groupBox14.SuspendLayout();
+ this.grpAbsoluteMotorPositionsTemperatures.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();
+ this.splitContainer1.Panel1.SuspendLayout();
+ this.splitContainer1.Panel2.SuspendLayout();
+ this.splitContainer1.SuspendLayout();
+ this.groupBox5.SuspendLayout();
+ this.tabPage3.SuspendLayout();
+ this.Encoders.SuspendLayout();
+ this.SensorNetworkSensorInitialization.SuspendLayout();
+ this.SoftwareStopsThresholdGroup.SuspendLayout();
+ this.grpProximitySensors.SuspendLayout();
+ this.MotorTemperatureSensors.SuspendLayout();
+ this.GatesSensors.SuspendLayout();
+ this.Accelerometers.SuspendLayout();
+ this.WeatherStation.SuspendLayout();
+ this.tabPage4.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.spectraCyberScanChart)).BeginInit();
+ this.tabPage5.SuspendLayout();
this.SuspendLayout();
//
// dataGridView1
@@ -136,74 +309,40 @@ private void InitializeComponent()
dataGridViewCellStyle1.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
dataGridViewCellStyle1.WrapMode = System.Windows.Forms.DataGridViewTriState.False;
this.dataGridView1.DefaultCellStyle = dataGridViewCellStyle1;
- this.dataGridView1.Location = new System.Drawing.Point(9, 10);
+ this.dataGridView1.Location = new System.Drawing.Point(3, 6);
this.dataGridView1.Margin = new System.Windows.Forms.Padding(2);
this.dataGridView1.Name = "dataGridView1";
this.dataGridView1.RowTemplate.Height = 24;
- this.dataGridView1.Size = new System.Drawing.Size(290, 178);
+ this.dataGridView1.Size = new System.Drawing.Size(331, 178);
this.dataGridView1.TabIndex = 0;
- this.dataGridView1.CellContentClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView1_CellContentClick);
//
- // lblCurrentAzOrientation
+ // windSpeedLabel
//
- this.lblCurrentAzOrientation.AutoSize = true;
- this.lblCurrentAzOrientation.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- this.lblCurrentAzOrientation.Location = new System.Drawing.Point(319, 19);
- this.lblCurrentAzOrientation.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
- this.lblCurrentAzOrientation.Name = "lblCurrentAzOrientation";
- this.lblCurrentAzOrientation.Size = new System.Drawing.Size(132, 20);
- this.lblCurrentAzOrientation.TabIndex = 1;
- this.lblCurrentAzOrientation.Text = "Current Azimuth: ";
+ this.windSpeedLabel.AutoSize = true;
+ this.windSpeedLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.windSpeedLabel.Location = new System.Drawing.Point(203, 46);
+ this.windSpeedLabel.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
+ this.windSpeedLabel.Name = "windSpeedLabel";
+ this.windSpeedLabel.Size = new System.Drawing.Size(22, 18);
+ this.windSpeedLabel.TabIndex = 3;
+ this.windSpeedLabel.Text = " --";
//
- // lblCurrentElOrientation
- //
- this.lblCurrentElOrientation.AutoSize = true;
- this.lblCurrentElOrientation.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- this.lblCurrentElOrientation.Location = new System.Drawing.Point(319, 46);
- this.lblCurrentElOrientation.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
- this.lblCurrentElOrientation.Name = "lblCurrentElOrientation";
- this.lblCurrentElOrientation.Size = new System.Drawing.Size(139, 20);
- this.lblCurrentElOrientation.TabIndex = 2;
- this.lblCurrentElOrientation.Text = "Current Elevation: ";
- //
- // label3
- //
- this.label3.AutoSize = true;
- this.label3.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- this.label3.Location = new System.Drawing.Point(466, 19);
- this.label3.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
- this.label3.Name = "label3";
- this.label3.Size = new System.Drawing.Size(31, 20);
- this.label3.TabIndex = 3;
- this.label3.Text = "0.0";
+ // windDirLabel
//
- // label4
- //
- this.label4.AutoSize = true;
- this.label4.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- this.label4.Location = new System.Drawing.Point(466, 46);
- this.label4.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
- this.label4.Name = "label4";
- this.label4.Size = new System.Drawing.Size(31, 20);
- this.label4.TabIndex = 4;
- this.label4.Text = "0.0";
- //
- // label5
- //
- this.label5.AutoSize = true;
- this.label5.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- this.label5.Location = new System.Drawing.Point(5, 211);
- this.label5.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
- this.label5.Name = "label5";
- this.label5.Size = new System.Drawing.Size(157, 20);
- this.label5.TabIndex = 5;
- this.label5.Text = "Current Appointment";
+ this.windDirLabel.AutoSize = true;
+ this.windDirLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.windDirLabel.Location = new System.Drawing.Point(202, 22);
+ this.windDirLabel.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
+ this.windDirLabel.Name = "windDirLabel";
+ this.windDirLabel.Size = new System.Drawing.Size(23, 20);
+ this.windDirLabel.TabIndex = 4;
+ this.windDirLabel.Text = " --";
//
// label6
//
this.label6.AutoSize = true;
this.label6.Font = new System.Drawing.Font("Microsoft Sans Serif", 10.2F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- this.label6.Location = new System.Drawing.Point(6, 243);
+ this.label6.Location = new System.Drawing.Point(2, 16);
this.label6.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.label6.Name = "label6";
this.label6.Size = new System.Drawing.Size(73, 17);
@@ -214,7 +353,7 @@ private void InitializeComponent()
//
this.label7.AutoSize = true;
this.label7.Font = new System.Drawing.Font("Microsoft Sans Serif", 10.2F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- this.label7.Location = new System.Drawing.Point(6, 296);
+ this.label7.Location = new System.Drawing.Point(2, 57);
this.label7.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.label7.Name = "label7";
this.label7.Size = new System.Drawing.Size(68, 17);
@@ -223,33 +362,33 @@ private void InitializeComponent()
//
// startTimeTextBox
//
- this.startTimeTextBox.Location = new System.Drawing.Point(9, 262);
+ this.startTimeTextBox.Location = new System.Drawing.Point(5, 35);
this.startTimeTextBox.Margin = new System.Windows.Forms.Padding(2);
this.startTimeTextBox.Name = "startTimeTextBox";
- this.startTimeTextBox.Size = new System.Drawing.Size(76, 20);
+ this.startTimeTextBox.Size = new System.Drawing.Size(135, 20);
this.startTimeTextBox.TabIndex = 8;
//
// endTimeTextBox
//
- this.endTimeTextBox.Location = new System.Drawing.Point(9, 314);
+ this.endTimeTextBox.Location = new System.Drawing.Point(5, 76);
this.endTimeTextBox.Margin = new System.Windows.Forms.Padding(2);
this.endTimeTextBox.Name = "endTimeTextBox";
- this.endTimeTextBox.Size = new System.Drawing.Size(76, 20);
+ this.endTimeTextBox.Size = new System.Drawing.Size(135, 20);
this.endTimeTextBox.TabIndex = 9;
//
// statusTextBox
//
- this.statusTextBox.Location = new System.Drawing.Point(116, 262);
+ this.statusTextBox.Location = new System.Drawing.Point(161, 57);
this.statusTextBox.Margin = new System.Windows.Forms.Padding(2);
this.statusTextBox.Name = "statusTextBox";
- this.statusTextBox.Size = new System.Drawing.Size(102, 20);
+ this.statusTextBox.Size = new System.Drawing.Size(103, 20);
this.statusTextBox.TabIndex = 10;
//
// label8
//
this.label8.AutoSize = true;
this.label8.Font = new System.Drawing.Font("Microsoft Sans Serif", 10.2F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- this.label8.Location = new System.Drawing.Point(112, 242);
+ this.label8.Location = new System.Drawing.Point(158, 35);
this.label8.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.label8.Name = "label8";
this.label8.Size = new System.Drawing.Size(48, 17);
@@ -264,416 +403,70 @@ private void InitializeComponent()
// lblAzimuthTemp
//
this.lblAzimuthTemp.AutoSize = true;
- this.lblAzimuthTemp.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- this.lblAzimuthTemp.Location = new System.Drawing.Point(529, 19);
+ this.lblAzimuthTemp.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.lblAzimuthTemp.Location = new System.Drawing.Point(10, 9);
this.lblAzimuthTemp.Name = "lblAzimuthTemp";
- this.lblAzimuthTemp.Size = new System.Drawing.Size(115, 20);
+ this.lblAzimuthTemp.Size = new System.Drawing.Size(152, 16);
this.lblAzimuthTemp.TabIndex = 14;
- this.lblAzimuthTemp.Text = "Azimuth Temp:";
+ this.lblAzimuthTemp.Text = "Azimuth Motor Temp:";
//
// lblElevationTemp
//
this.lblElevationTemp.AutoSize = true;
- this.lblElevationTemp.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- this.lblElevationTemp.Location = new System.Drawing.Point(522, 49);
+ this.lblElevationTemp.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.lblElevationTemp.Location = new System.Drawing.Point(11, 26);
this.lblElevationTemp.Name = "lblElevationTemp";
- this.lblElevationTemp.Size = new System.Drawing.Size(122, 20);
+ this.lblElevationTemp.Size = new System.Drawing.Size(164, 16);
this.lblElevationTemp.TabIndex = 15;
- this.lblElevationTemp.Text = "Elevation Temp:";
- //
- // radioButton1
- //
- this.radioButton1.AutoSize = true;
- this.radioButton1.Location = new System.Drawing.Point(622, 89);
- this.radioButton1.Name = "radioButton1";
- this.radioButton1.Size = new System.Drawing.Size(59, 17);
- this.radioButton1.TabIndex = 16;
- this.radioButton1.TabStop = true;
- this.radioButton1.Text = "Celcius";
- this.radioButton1.UseVisualStyleBackColor = true;
- //
- // radioButton2
- //
- this.radioButton2.AutoSize = true;
- this.radioButton2.Location = new System.Drawing.Point(526, 89);
- this.radioButton2.Name = "radioButton2";
- this.radioButton2.Size = new System.Drawing.Size(75, 17);
- this.radioButton2.TabIndex = 17;
- this.radioButton2.TabStop = true;
- this.radioButton2.Text = "Fahrenheit";
- this.radioButton2.UseVisualStyleBackColor = true;
+ this.lblElevationTemp.Text = "Elevation Motor Temp:";
//
// fldAzTemp
//
this.fldAzTemp.AutoSize = true;
- this.fldAzTemp.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- this.fldAzTemp.Location = new System.Drawing.Point(650, 19);
+ this.fldAzTemp.Font = new System.Drawing.Font("Microsoft Sans Serif", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.fldAzTemp.Location = new System.Drawing.Point(202, 7);
this.fldAzTemp.Name = "fldAzTemp";
- this.fldAzTemp.Size = new System.Drawing.Size(31, 20);
+ this.fldAzTemp.Size = new System.Drawing.Size(18, 18);
this.fldAzTemp.TabIndex = 18;
- this.fldAzTemp.Text = "0.0";
+ this.fldAzTemp.Text = "--";
//
// fldElTemp
//
this.fldElTemp.AutoSize = true;
- this.fldElTemp.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- this.fldElTemp.Location = new System.Drawing.Point(650, 49);
+ this.fldElTemp.Font = new System.Drawing.Font("Microsoft Sans Serif", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.fldElTemp.Location = new System.Drawing.Point(202, 29);
this.fldElTemp.Name = "fldElTemp";
- this.fldElTemp.Size = new System.Drawing.Size(31, 20);
+ this.fldElTemp.Size = new System.Drawing.Size(18, 18);
this.fldElTemp.TabIndex = 19;
- this.fldElTemp.Text = "0.0";
- //
- // txtTemperature
- //
- this.txtTemperature.Location = new System.Drawing.Point(833, 23);
- this.txtTemperature.Name = "txtTemperature";
- this.txtTemperature.Size = new System.Drawing.Size(39, 20);
- this.txtTemperature.TabIndex = 20;
+ this.fldElTemp.Text = "--";
//
// btnTest
//
- this.btnTest.Location = new System.Drawing.Point(823, 53);
+ this.btnTest.BackColor = System.Drawing.Color.LimeGreen;
+ this.btnTest.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+ this.btnTest.Location = new System.Drawing.Point(115, 16);
this.btnTest.Name = "btnTest";
- this.btnTest.Size = new System.Drawing.Size(59, 34);
+ this.btnTest.Size = new System.Drawing.Size(69, 27);
this.btnTest.TabIndex = 21;
- this.btnTest.Text = "Test Button";
- this.btnTest.UseVisualStyleBackColor = true;
+ this.btnTest.Text = "Test ";
+ this.btnTest.UseVisualStyleBackColor = false;
this.btnTest.Click += new System.EventHandler(this.btnTest_Click);
//
- // warningLabel
- //
- this.warningLabel.AutoSize = true;
- this.warningLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- this.warningLabel.ForeColor = System.Drawing.Color.Chartreuse;
- this.warningLabel.Location = new System.Drawing.Point(706, 46);
- this.warningLabel.Name = "warningLabel";
- this.warningLabel.Size = new System.Drawing.Size(100, 16);
- this.warningLabel.TabIndex = 22;
- this.warningLabel.Text = "warningLabel";
- this.warningLabel.Visible = false;
- //
- // fanLabel
- //
- this.fanLabel.AutoSize = true;
- this.fanLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- this.fanLabel.ForeColor = System.Drawing.Color.Chartreuse;
- this.fanLabel.Location = new System.Drawing.Point(717, 23);
- this.fanLabel.Name = "fanLabel";
- this.fanLabel.Size = new System.Drawing.Size(68, 16);
- this.fanLabel.TabIndex = 23;
- this.fanLabel.Text = "fanLabel";
- this.fanLabel.Visible = false;
- //
- // btnAddOneTemp
- //
- this.btnAddOneTemp.Location = new System.Drawing.Point(521, 117);
- this.btnAddOneTemp.Name = "btnAddOneTemp";
- this.btnAddOneTemp.Size = new System.Drawing.Size(35, 35);
- this.btnAddOneTemp.TabIndex = 24;
- this.btnAddOneTemp.Text = "+1";
- this.btnAddOneTemp.UseVisualStyleBackColor = true;
- this.btnAddOneTemp.Click += new System.EventHandler(this.btnAddOneTemp_Click);
- //
- // btnAddFiveTemp
- //
- this.btnAddFiveTemp.Location = new System.Drawing.Point(574, 117);
- this.btnAddFiveTemp.Name = "btnAddFiveTemp";
- this.btnAddFiveTemp.Size = new System.Drawing.Size(35, 35);
- this.btnAddFiveTemp.TabIndex = 25;
- this.btnAddFiveTemp.Text = "+5";
- this.btnAddFiveTemp.UseVisualStyleBackColor = true;
- this.btnAddFiveTemp.Click += new System.EventHandler(this.btnAddFiveTemp_Click);
- //
- // btnAddXTemp
- //
- this.btnAddXTemp.Location = new System.Drawing.Point(622, 117);
- this.btnAddXTemp.Name = "btnAddXTemp";
- this.btnAddXTemp.Size = new System.Drawing.Size(35, 35);
- this.btnAddXTemp.TabIndex = 26;
- this.btnAddXTemp.Text = "+X";
- this.btnAddXTemp.UseVisualStyleBackColor = true;
- this.btnAddXTemp.Click += new System.EventHandler(this.btnAddXTemp_Click);
- //
- // lblShutdown
- //
- this.lblShutdown.AutoSize = true;
- this.lblShutdown.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- this.lblShutdown.ForeColor = System.Drawing.Color.Chartreuse;
- this.lblShutdown.Location = new System.Drawing.Point(706, 71);
- this.lblShutdown.Name = "lblShutdown";
- this.lblShutdown.Size = new System.Drawing.Size(111, 16);
- this.lblShutdown.TabIndex = 27;
- this.lblShutdown.Text = "shutdownLabel";
- this.lblShutdown.Visible = false;
- //
// selectDemo
//
this.selectDemo.AutoSize = true;
- this.selectDemo.Location = new System.Drawing.Point(720, 102);
+ this.selectDemo.Location = new System.Drawing.Point(13, 22);
this.selectDemo.Name = "selectDemo";
this.selectDemo.Size = new System.Drawing.Size(77, 17);
this.selectDemo.TabIndex = 29;
this.selectDemo.Text = "Run Demo";
this.selectDemo.UseVisualStyleBackColor = true;
//
- // btnSubtractOneTemp
- //
- this.btnSubtractOneTemp.Location = new System.Drawing.Point(521, 158);
- this.btnSubtractOneTemp.Name = "btnSubtractOneTemp";
- this.btnSubtractOneTemp.Size = new System.Drawing.Size(35, 35);
- this.btnSubtractOneTemp.TabIndex = 30;
- this.btnSubtractOneTemp.Text = "-1";
- this.btnSubtractOneTemp.UseVisualStyleBackColor = true;
- this.btnSubtractOneTemp.Click += new System.EventHandler(this.button1_Click);
- //
- // btnSubtractFiveTemp
- //
- this.btnSubtractFiveTemp.Location = new System.Drawing.Point(574, 158);
- this.btnSubtractFiveTemp.Name = "btnSubtractFiveTemp";
- this.btnSubtractFiveTemp.Size = new System.Drawing.Size(35, 35);
- this.btnSubtractFiveTemp.TabIndex = 31;
- this.btnSubtractFiveTemp.Text = "-5";
- this.btnSubtractFiveTemp.UseVisualStyleBackColor = true;
- this.btnSubtractFiveTemp.Click += new System.EventHandler(this.button2_Click);
- //
- // btnSubtractXTemp
- //
- this.btnSubtractXTemp.Location = new System.Drawing.Point(622, 158);
- this.btnSubtractXTemp.Name = "btnSubtractXTemp";
- this.btnSubtractXTemp.Size = new System.Drawing.Size(35, 35);
- this.btnSubtractXTemp.TabIndex = 32;
- this.btnSubtractXTemp.Text = "-X";
- this.btnSubtractXTemp.UseVisualStyleBackColor = true;
- this.btnSubtractXTemp.Click += new System.EventHandler(this.button3_Click);
- //
- // txtCustTemp
- //
- this.txtCustTemp.Location = new System.Drawing.Point(673, 158);
- this.txtCustTemp.Name = "txtCustTemp";
- this.txtCustTemp.Size = new System.Drawing.Size(51, 20);
- this.txtCustTemp.TabIndex = 33;
- //
- // label11
- //
- this.label11.AutoSize = true;
- this.label11.Location = new System.Drawing.Point(663, 128);
- this.label11.Name = "label11";
- this.label11.Size = new System.Drawing.Size(72, 13);
- this.label11.TabIndex = 34;
- this.label11.Text = "Custom Value";
- //
- // panel1
- //
- this.panel1.BackColor = System.Drawing.SystemColors.GradientInactiveCaption;
- this.panel1.Controls.Add(this.lblElLimStatus2);
- this.panel1.Controls.Add(this.lblElLimStatus1);
- this.panel1.Controls.Add(this.lblAzLimStatus2);
- this.panel1.Controls.Add(this.lblAzLimStatus1);
- this.panel1.Controls.Add(this.lblElLimit2);
- this.panel1.Controls.Add(this.lblElLimit1);
- this.panel1.Controls.Add(this.lblAzLimit2);
- this.panel1.Controls.Add(this.lblAzLimit1);
- this.panel1.Controls.Add(this.lblEleProx2);
- this.panel1.Controls.Add(this.lblEleProx1);
- this.panel1.Controls.Add(this.lblElProx2);
- this.panel1.Controls.Add(this.lblElProx1);
- this.panel1.Controls.Add(this.lblAzProxStatus3);
- this.panel1.Controls.Add(this.lblAzProxStatus2);
- this.panel1.Controls.Add(this.lblAzProxStatus1);
- this.panel1.Controls.Add(this.lblAzProx3);
- this.panel1.Controls.Add(this.lblAzProx2);
- this.panel1.Controls.Add(this.lblAzProx1);
- this.panel1.Location = new System.Drawing.Point(495, 223);
- this.panel1.Name = "panel1";
- this.panel1.Size = new System.Drawing.Size(377, 344);
- this.panel1.TabIndex = 35;
- //
- // lblElLimStatus2
- //
- this.lblElLimStatus2.AutoSize = true;
- this.lblElLimStatus2.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- this.lblElLimStatus2.Location = new System.Drawing.Point(223, 309);
- this.lblElLimStatus2.Name = "lblElLimStatus2";
- this.lblElLimStatus2.Size = new System.Drawing.Size(56, 15);
- this.lblElLimStatus2.TabIndex = 17;
- this.lblElLimStatus2.Text = "Inactive";
- //
- // lblElLimStatus1
- //
- this.lblElLimStatus1.AutoSize = true;
- this.lblElLimStatus1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- this.lblElLimStatus1.Location = new System.Drawing.Point(223, 271);
- this.lblElLimStatus1.Name = "lblElLimStatus1";
- this.lblElLimStatus1.Size = new System.Drawing.Size(56, 15);
- this.lblElLimStatus1.TabIndex = 16;
- this.lblElLimStatus1.Text = "Inactive";
- //
- // lblAzLimStatus2
- //
- this.lblAzLimStatus2.AutoSize = true;
- this.lblAzLimStatus2.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- this.lblAzLimStatus2.Location = new System.Drawing.Point(223, 231);
- this.lblAzLimStatus2.Name = "lblAzLimStatus2";
- this.lblAzLimStatus2.Size = new System.Drawing.Size(56, 15);
- this.lblAzLimStatus2.TabIndex = 15;
- this.lblAzLimStatus2.Text = "Inactive";
- this.lblAzLimStatus2.Click += new System.EventHandler(this.lblAzLimStatus2_Click);
- //
- // lblAzLimStatus1
- //
- this.lblAzLimStatus1.AutoSize = true;
- this.lblAzLimStatus1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- this.lblAzLimStatus1.Location = new System.Drawing.Point(223, 193);
- this.lblAzLimStatus1.Name = "lblAzLimStatus1";
- this.lblAzLimStatus1.Size = new System.Drawing.Size(56, 15);
- this.lblAzLimStatus1.TabIndex = 14;
- this.lblAzLimStatus1.Text = "Inactive";
- //
- // lblElLimit2
- //
- this.lblElLimit2.AutoSize = true;
- this.lblElLimit2.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- this.lblElLimit2.Location = new System.Drawing.Point(14, 309);
- this.lblElLimit2.Name = "lblElLimit2";
- this.lblElLimit2.Size = new System.Drawing.Size(160, 15);
- this.lblElLimit2.TabIndex = 13;
- this.lblElLimit2.Text = "Elevation Limit Switch 2";
- //
- // lblElLimit1
- //
- this.lblElLimit1.AutoSize = true;
- this.lblElLimit1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- this.lblElLimit1.Location = new System.Drawing.Point(14, 271);
- this.lblElLimit1.Name = "lblElLimit1";
- this.lblElLimit1.Size = new System.Drawing.Size(160, 15);
- this.lblElLimit1.TabIndex = 12;
- this.lblElLimit1.Text = "Elevation Limit Switch 1";
- //
- // lblAzLimit2
- //
- this.lblAzLimit2.AutoSize = true;
- this.lblAzLimit2.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- this.lblAzLimit2.Location = new System.Drawing.Point(14, 231);
- this.lblAzLimit2.Name = "lblAzLimit2";
- this.lblAzLimit2.Size = new System.Drawing.Size(152, 15);
- this.lblAzLimit2.TabIndex = 11;
- this.lblAzLimit2.Text = "Azimuth Limit Switch 1";
- //
- // lblAzLimit1
- //
- this.lblAzLimit1.AutoSize = true;
- this.lblAzLimit1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- this.lblAzLimit1.Location = new System.Drawing.Point(14, 193);
- this.lblAzLimit1.Name = "lblAzLimit1";
- this.lblAzLimit1.Size = new System.Drawing.Size(152, 15);
- this.lblAzLimit1.TabIndex = 10;
- this.lblAzLimit1.Text = "Azimuth Limit Switch 1";
- //
- // lblEleProx2
- //
- this.lblEleProx2.AutoSize = true;
- this.lblEleProx2.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- this.lblEleProx2.Location = new System.Drawing.Point(223, 155);
- this.lblEleProx2.Name = "lblEleProx2";
- this.lblEleProx2.Size = new System.Drawing.Size(56, 15);
- this.lblEleProx2.TabIndex = 9;
- this.lblEleProx2.Text = "Inactive";
- //
- // lblEleProx1
- //
- this.lblEleProx1.AutoSize = true;
- this.lblEleProx1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- this.lblEleProx1.Location = new System.Drawing.Point(223, 118);
- this.lblEleProx1.Name = "lblEleProx1";
- this.lblEleProx1.Size = new System.Drawing.Size(56, 15);
- this.lblEleProx1.TabIndex = 8;
- this.lblEleProx1.Text = "Inactive";
- //
- // lblElProx2
- //
- this.lblElProx2.AutoSize = true;
- this.lblElProx2.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- this.lblElProx2.Location = new System.Drawing.Point(14, 155);
- this.lblElProx2.Name = "lblElProx2";
- this.lblElProx2.Size = new System.Drawing.Size(190, 15);
- this.lblElProx2.TabIndex = 7;
- this.lblElProx2.Text = "Elevation Proximity Sensor 2";
- //
- // lblElProx1
- //
- this.lblElProx1.AutoSize = true;
- this.lblElProx1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- this.lblElProx1.Location = new System.Drawing.Point(14, 118);
- this.lblElProx1.Name = "lblElProx1";
- this.lblElProx1.Size = new System.Drawing.Size(190, 15);
- this.lblElProx1.TabIndex = 6;
- this.lblElProx1.Text = "Elevation Proximity Sensor 1";
- //
- // lblAzProxStatus3
- //
- this.lblAzProxStatus3.AutoSize = true;
- this.lblAzProxStatus3.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- this.lblAzProxStatus3.Location = new System.Drawing.Point(223, 83);
- this.lblAzProxStatus3.Name = "lblAzProxStatus3";
- this.lblAzProxStatus3.Size = new System.Drawing.Size(56, 15);
- this.lblAzProxStatus3.TabIndex = 5;
- this.lblAzProxStatus3.Text = "Inactive";
- //
- // lblAzProxStatus2
- //
- this.lblAzProxStatus2.AutoSize = true;
- this.lblAzProxStatus2.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- this.lblAzProxStatus2.Location = new System.Drawing.Point(223, 50);
- this.lblAzProxStatus2.Name = "lblAzProxStatus2";
- this.lblAzProxStatus2.Size = new System.Drawing.Size(56, 15);
- this.lblAzProxStatus2.TabIndex = 4;
- this.lblAzProxStatus2.Text = "Inactive";
- //
- // lblAzProxStatus1
- //
- this.lblAzProxStatus1.AutoSize = true;
- this.lblAzProxStatus1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- this.lblAzProxStatus1.Location = new System.Drawing.Point(223, 18);
- this.lblAzProxStatus1.Name = "lblAzProxStatus1";
- this.lblAzProxStatus1.Size = new System.Drawing.Size(56, 15);
- this.lblAzProxStatus1.TabIndex = 3;
- this.lblAzProxStatus1.Text = "Inactive";
- //
- // lblAzProx3
- //
- this.lblAzProx3.AutoSize = true;
- this.lblAzProx3.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- this.lblAzProx3.Location = new System.Drawing.Point(14, 83);
- this.lblAzProx3.Name = "lblAzProx3";
- this.lblAzProx3.Size = new System.Drawing.Size(182, 15);
- this.lblAzProx3.TabIndex = 2;
- this.lblAzProx3.Text = "Azimuth Proximity Sensor 3";
- //
- // lblAzProx2
- //
- this.lblAzProx2.AutoSize = true;
- this.lblAzProx2.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- this.lblAzProx2.Location = new System.Drawing.Point(14, 50);
- this.lblAzProx2.Name = "lblAzProx2";
- this.lblAzProx2.Size = new System.Drawing.Size(182, 15);
- this.lblAzProx2.TabIndex = 1;
- this.lblAzProx2.Text = "Azimuth Proximity Sensor 2";
- //
- // lblAzProx1
- //
- this.lblAzProx1.AutoSize = true;
- this.lblAzProx1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- this.lblAzProx1.Location = new System.Drawing.Point(14, 18);
- this.lblAzProx1.Name = "lblAzProx1";
- this.lblAzProx1.Size = new System.Drawing.Size(182, 15);
- this.lblAzProx1.TabIndex = 0;
- this.lblAzProx1.Text = "Azimuth Proximity Sensor 1";
- //
// lblAbsEncoder
//
this.lblAbsEncoder.AutoSize = true;
this.lblAbsEncoder.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- this.lblAbsEncoder.Location = new System.Drawing.Point(32, 367);
+ this.lblAbsEncoder.Location = new System.Drawing.Point(12, 2);
this.lblAbsEncoder.Name = "lblAbsEncoder";
this.lblAbsEncoder.Size = new System.Drawing.Size(115, 15);
this.lblAbsEncoder.TabIndex = 36;
@@ -682,7 +475,7 @@ private void InitializeComponent()
// lblEncoderDegrees
//
this.lblEncoderDegrees.AutoSize = true;
- this.lblEncoderDegrees.Location = new System.Drawing.Point(32, 394);
+ this.lblEncoderDegrees.Location = new System.Drawing.Point(13, 29);
this.lblEncoderDegrees.Name = "lblEncoderDegrees";
this.lblEncoderDegrees.Size = new System.Drawing.Size(47, 13);
this.lblEncoderDegrees.TabIndex = 37;
@@ -691,7 +484,7 @@ private void InitializeComponent()
// lblAzEncoderDegrees
//
this.lblAzEncoderDegrees.AutoSize = true;
- this.lblAzEncoderDegrees.Location = new System.Drawing.Point(96, 394);
+ this.lblAzEncoderDegrees.Location = new System.Drawing.Point(61, 29);
this.lblAzEncoderDegrees.Name = "lblAzEncoderDegrees";
this.lblAzEncoderDegrees.Size = new System.Drawing.Size(13, 13);
this.lblAzEncoderDegrees.TabIndex = 38;
@@ -700,7 +493,7 @@ private void InitializeComponent()
// lblEncoderTicks
//
this.lblEncoderTicks.AutoSize = true;
- this.lblEncoderTicks.Location = new System.Drawing.Point(31, 417);
+ this.lblEncoderTicks.Location = new System.Drawing.Point(12, 52);
this.lblEncoderTicks.Name = "lblEncoderTicks";
this.lblEncoderTicks.Size = new System.Drawing.Size(33, 13);
this.lblEncoderTicks.TabIndex = 39;
@@ -709,7 +502,7 @@ private void InitializeComponent()
// lblAzEncoderTicks
//
this.lblAzEncoderTicks.AutoSize = true;
- this.lblAzEncoderTicks.Location = new System.Drawing.Point(96, 417);
+ this.lblAzEncoderTicks.Location = new System.Drawing.Point(61, 52);
this.lblAzEncoderTicks.Name = "lblAzEncoderTicks";
this.lblAzEncoderTicks.Size = new System.Drawing.Size(13, 13);
this.lblAzEncoderTicks.TabIndex = 40;
@@ -717,68 +510,86 @@ private void InitializeComponent()
//
// btnAddOneEncoder
//
- this.btnAddOneEncoder.Location = new System.Drawing.Point(10, 437);
+ this.btnAddOneEncoder.BackColor = System.Drawing.Color.DarkGray;
+ this.btnAddOneEncoder.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+ this.btnAddOneEncoder.Location = new System.Drawing.Point(113, 23);
+ this.btnAddOneEncoder.Margin = new System.Windows.Forms.Padding(2);
this.btnAddOneEncoder.Name = "btnAddOneEncoder";
- this.btnAddOneEncoder.Size = new System.Drawing.Size(35, 35);
+ this.btnAddOneEncoder.Size = new System.Drawing.Size(33, 24);
this.btnAddOneEncoder.TabIndex = 41;
this.btnAddOneEncoder.Text = "+1";
- this.btnAddOneEncoder.UseVisualStyleBackColor = true;
+ this.btnAddOneEncoder.UseVisualStyleBackColor = false;
this.btnAddOneEncoder.Click += new System.EventHandler(this.button4_Click);
//
// btnAddFiveEncoder
//
- this.btnAddFiveEncoder.Location = new System.Drawing.Point(54, 437);
+ this.btnAddFiveEncoder.BackColor = System.Drawing.Color.DarkGray;
+ this.btnAddFiveEncoder.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+ this.btnAddFiveEncoder.Location = new System.Drawing.Point(162, 23);
+ this.btnAddFiveEncoder.Margin = new System.Windows.Forms.Padding(2);
this.btnAddFiveEncoder.Name = "btnAddFiveEncoder";
- this.btnAddFiveEncoder.Size = new System.Drawing.Size(35, 35);
+ this.btnAddFiveEncoder.Size = new System.Drawing.Size(33, 24);
this.btnAddFiveEncoder.TabIndex = 42;
this.btnAddFiveEncoder.Text = "+5";
- this.btnAddFiveEncoder.UseVisualStyleBackColor = true;
+ this.btnAddFiveEncoder.UseVisualStyleBackColor = false;
this.btnAddFiveEncoder.Click += new System.EventHandler(this.button5_Click);
//
// btnAddXEncoder
//
- this.btnAddXEncoder.Location = new System.Drawing.Point(96, 437);
+ this.btnAddXEncoder.BackColor = System.Drawing.Color.DarkGray;
+ this.btnAddXEncoder.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+ this.btnAddXEncoder.Location = new System.Drawing.Point(209, 23);
+ this.btnAddXEncoder.Margin = new System.Windows.Forms.Padding(2);
this.btnAddXEncoder.Name = "btnAddXEncoder";
- this.btnAddXEncoder.Size = new System.Drawing.Size(35, 35);
+ this.btnAddXEncoder.Size = new System.Drawing.Size(33, 24);
this.btnAddXEncoder.TabIndex = 43;
this.btnAddXEncoder.Text = "+X";
- this.btnAddXEncoder.UseVisualStyleBackColor = true;
+ this.btnAddXEncoder.UseVisualStyleBackColor = false;
this.btnAddXEncoder.Click += new System.EventHandler(this.btnAddXEncoder_Click);
//
// btnSubtractOneEncoder
//
- this.btnSubtractOneEncoder.Location = new System.Drawing.Point(9, 478);
+ this.btnSubtractOneEncoder.BackColor = System.Drawing.Color.DarkGray;
+ this.btnSubtractOneEncoder.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+ this.btnSubtractOneEncoder.Location = new System.Drawing.Point(114, 53);
+ this.btnSubtractOneEncoder.Margin = new System.Windows.Forms.Padding(2);
this.btnSubtractOneEncoder.Name = "btnSubtractOneEncoder";
- this.btnSubtractOneEncoder.Size = new System.Drawing.Size(35, 35);
+ this.btnSubtractOneEncoder.Size = new System.Drawing.Size(33, 24);
this.btnSubtractOneEncoder.TabIndex = 44;
this.btnSubtractOneEncoder.Text = "-1";
- this.btnSubtractOneEncoder.UseVisualStyleBackColor = true;
+ this.btnSubtractOneEncoder.UseVisualStyleBackColor = false;
this.btnSubtractOneEncoder.Click += new System.EventHandler(this.btnSubtractOneEncoder_Click);
//
// btnSubtractFiveEncoder
//
- this.btnSubtractFiveEncoder.Location = new System.Drawing.Point(54, 478);
+ this.btnSubtractFiveEncoder.BackColor = System.Drawing.Color.DarkGray;
+ this.btnSubtractFiveEncoder.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+ this.btnSubtractFiveEncoder.Location = new System.Drawing.Point(162, 53);
+ this.btnSubtractFiveEncoder.Margin = new System.Windows.Forms.Padding(2);
this.btnSubtractFiveEncoder.Name = "btnSubtractFiveEncoder";
- this.btnSubtractFiveEncoder.Size = new System.Drawing.Size(35, 35);
+ this.btnSubtractFiveEncoder.Size = new System.Drawing.Size(33, 24);
this.btnSubtractFiveEncoder.TabIndex = 45;
this.btnSubtractFiveEncoder.Text = "-5";
- this.btnSubtractFiveEncoder.UseVisualStyleBackColor = true;
+ this.btnSubtractFiveEncoder.UseVisualStyleBackColor = false;
this.btnSubtractFiveEncoder.Click += new System.EventHandler(this.btnSubtractFiveEncoder_Click);
//
// btnSubtractXEncoder
//
- this.btnSubtractXEncoder.Location = new System.Drawing.Point(95, 478);
+ this.btnSubtractXEncoder.BackColor = System.Drawing.Color.DarkGray;
+ this.btnSubtractXEncoder.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+ this.btnSubtractXEncoder.Location = new System.Drawing.Point(209, 53);
+ this.btnSubtractXEncoder.Margin = new System.Windows.Forms.Padding(2);
this.btnSubtractXEncoder.Name = "btnSubtractXEncoder";
- this.btnSubtractXEncoder.Size = new System.Drawing.Size(35, 35);
+ this.btnSubtractXEncoder.Size = new System.Drawing.Size(33, 24);
this.btnSubtractXEncoder.TabIndex = 46;
this.btnSubtractXEncoder.Text = "-X";
- this.btnSubtractXEncoder.UseVisualStyleBackColor = true;
+ this.btnSubtractXEncoder.UseVisualStyleBackColor = false;
this.btnSubtractXEncoder.Click += new System.EventHandler(this.btnSubtractXEncoder_Click);
//
// label9
//
this.label9.AutoSize = true;
- this.label9.Location = new System.Drawing.Point(137, 448);
+ this.label9.Location = new System.Drawing.Point(265, 18);
this.label9.Name = "label9";
this.label9.Size = new System.Drawing.Size(72, 13);
this.label9.TabIndex = 47;
@@ -786,14 +597,14 @@ private void InitializeComponent()
//
// txtCustEncoderVal
//
- this.txtCustEncoderVal.Location = new System.Drawing.Point(140, 478);
+ this.txtCustEncoderVal.Location = new System.Drawing.Point(268, 48);
this.txtCustEncoderVal.Name = "txtCustEncoderVal";
this.txtCustEncoderVal.Size = new System.Drawing.Size(51, 20);
this.txtCustEncoderVal.TabIndex = 48;
//
// textBox1
//
- this.textBox1.Location = new System.Drawing.Point(378, 478);
+ this.textBox1.Location = new System.Drawing.Point(269, 44);
this.textBox1.Name = "textBox1";
this.textBox1.Size = new System.Drawing.Size(51, 20);
this.textBox1.TabIndex = 56;
@@ -801,7 +612,7 @@ private void InitializeComponent()
// label10
//
this.label10.AutoSize = true;
- this.label10.Location = new System.Drawing.Point(375, 448);
+ this.label10.Location = new System.Drawing.Point(266, 14);
this.label10.Name = "label10";
this.label10.Size = new System.Drawing.Size(72, 13);
this.label10.TabIndex = 55;
@@ -809,62 +620,80 @@ private void InitializeComponent()
//
// button1
//
- this.button1.Location = new System.Drawing.Point(333, 478);
+ this.button1.BackColor = System.Drawing.Color.DarkGray;
+ this.button1.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+ this.button1.Location = new System.Drawing.Point(209, 57);
+ this.button1.Margin = new System.Windows.Forms.Padding(2);
this.button1.Name = "button1";
- this.button1.Size = new System.Drawing.Size(35, 35);
+ this.button1.Size = new System.Drawing.Size(33, 24);
this.button1.TabIndex = 54;
this.button1.Text = "-X";
- this.button1.UseVisualStyleBackColor = true;
+ this.button1.UseVisualStyleBackColor = false;
//
// button2
//
- this.button2.Location = new System.Drawing.Point(292, 478);
+ this.button2.BackColor = System.Drawing.Color.DarkGray;
+ this.button2.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+ this.button2.Location = new System.Drawing.Point(162, 57);
+ this.button2.Margin = new System.Windows.Forms.Padding(2);
this.button2.Name = "button2";
- this.button2.Size = new System.Drawing.Size(35, 35);
+ this.button2.Size = new System.Drawing.Size(33, 24);
this.button2.TabIndex = 53;
this.button2.Text = "-5";
- this.button2.UseVisualStyleBackColor = true;
+ this.button2.UseVisualStyleBackColor = false;
//
// button3
//
- this.button3.Location = new System.Drawing.Point(247, 478);
+ this.button3.BackColor = System.Drawing.Color.DarkGray;
+ this.button3.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+ this.button3.Location = new System.Drawing.Point(112, 57);
+ this.button3.Margin = new System.Windows.Forms.Padding(2);
this.button3.Name = "button3";
- this.button3.Size = new System.Drawing.Size(35, 35);
+ this.button3.Size = new System.Drawing.Size(33, 24);
this.button3.TabIndex = 52;
this.button3.Text = "-1";
- this.button3.UseVisualStyleBackColor = true;
+ this.button3.UseVisualStyleBackColor = false;
//
// button4
//
- this.button4.Location = new System.Drawing.Point(334, 437);
+ this.button4.BackColor = System.Drawing.Color.DarkGray;
+ this.button4.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+ this.button4.Location = new System.Drawing.Point(209, 25);
+ this.button4.Margin = new System.Windows.Forms.Padding(2);
this.button4.Name = "button4";
- this.button4.Size = new System.Drawing.Size(35, 35);
+ this.button4.Size = new System.Drawing.Size(33, 24);
this.button4.TabIndex = 51;
this.button4.Text = "+X";
- this.button4.UseVisualStyleBackColor = true;
+ this.button4.UseVisualStyleBackColor = false;
//
// button5
//
- this.button5.Location = new System.Drawing.Point(292, 437);
+ this.button5.BackColor = System.Drawing.Color.DarkGray;
+ this.button5.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+ this.button5.Location = new System.Drawing.Point(162, 25);
+ this.button5.Margin = new System.Windows.Forms.Padding(2);
this.button5.Name = "button5";
- this.button5.Size = new System.Drawing.Size(35, 35);
+ this.button5.Size = new System.Drawing.Size(33, 24);
this.button5.TabIndex = 50;
this.button5.Text = "+5";
- this.button5.UseVisualStyleBackColor = true;
+ this.button5.UseVisualStyleBackColor = false;
//
// button6
//
- this.button6.Location = new System.Drawing.Point(248, 437);
+ this.button6.BackColor = System.Drawing.Color.DarkGray;
+ this.button6.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+ this.button6.Location = new System.Drawing.Point(113, 25);
+ this.button6.Margin = new System.Windows.Forms.Padding(2);
this.button6.Name = "button6";
- this.button6.Size = new System.Drawing.Size(35, 35);
+ this.button6.Size = new System.Drawing.Size(33, 24);
this.button6.TabIndex = 49;
this.button6.Text = "+1";
- this.button6.UseVisualStyleBackColor = true;
+ this.button6.UseVisualStyleBackColor = false;
//
// lblElEncoderTicks
//
this.lblElEncoderTicks.AutoSize = true;
- this.lblElEncoderTicks.Location = new System.Drawing.Point(341, 417);
+ this.lblElEncoderTicks.Location = new System.Drawing.Point(61, 59);
this.lblElEncoderTicks.Name = "lblElEncoderTicks";
this.lblElEncoderTicks.Size = new System.Drawing.Size(13, 13);
this.lblElEncoderTicks.TabIndex = 61;
@@ -873,7 +702,7 @@ private void InitializeComponent()
// label14
//
this.label14.AutoSize = true;
- this.label14.Location = new System.Drawing.Point(276, 417);
+ this.label14.Location = new System.Drawing.Point(10, 59);
this.label14.Name = "label14";
this.label14.Size = new System.Drawing.Size(33, 13);
this.label14.TabIndex = 60;
@@ -882,7 +711,7 @@ private void InitializeComponent()
// lblElEncoderDegrees
//
this.lblElEncoderDegrees.AutoSize = true;
- this.lblElEncoderDegrees.Location = new System.Drawing.Point(341, 394);
+ this.lblElEncoderDegrees.Location = new System.Drawing.Point(60, 36);
this.lblElEncoderDegrees.Name = "lblElEncoderDegrees";
this.lblElEncoderDegrees.Size = new System.Drawing.Size(13, 13);
this.lblElEncoderDegrees.TabIndex = 59;
@@ -891,7 +720,7 @@ private void InitializeComponent()
// label16
//
this.label16.AutoSize = true;
- this.label16.Location = new System.Drawing.Point(277, 394);
+ this.label16.Location = new System.Drawing.Point(10, 36);
this.label16.Name = "label16";
this.label16.Size = new System.Drawing.Size(47, 13);
this.label16.TabIndex = 58;
@@ -901,7 +730,7 @@ private void InitializeComponent()
//
this.label17.AutoSize = true;
this.label17.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- this.label17.Location = new System.Drawing.Point(277, 367);
+ this.label17.Location = new System.Drawing.Point(4, 9);
this.label17.Name = "label17";
this.label17.Size = new System.Drawing.Size(123, 15);
this.label17.TabIndex = 57;
@@ -910,7 +739,7 @@ private void InitializeComponent()
// label12
//
this.label12.AutoSize = true;
- this.label12.Location = new System.Drawing.Point(12, 543);
+ this.label12.Location = new System.Drawing.Point(3, 105);
this.label12.Name = "label12";
this.label12.Size = new System.Drawing.Size(101, 13);
this.label12.TabIndex = 62;
@@ -918,7 +747,7 @@ private void InitializeComponent()
//
// textBox2
//
- this.textBox2.Location = new System.Drawing.Point(30, 559);
+ this.textBox2.Location = new System.Drawing.Point(137, 42);
this.textBox2.Name = "textBox2";
this.textBox2.Size = new System.Drawing.Size(39, 20);
this.textBox2.TabIndex = 63;
@@ -926,7 +755,7 @@ private void InitializeComponent()
// label13
//
this.label13.AutoSize = true;
- this.label13.Location = new System.Drawing.Point(26, 582);
+ this.label13.Location = new System.Drawing.Point(3, 42);
this.label13.Name = "label13";
this.label13.Size = new System.Drawing.Size(48, 13);
this.label13.TabIndex = 64;
@@ -942,14 +771,14 @@ private void InitializeComponent()
//
// textBox3
//
- this.textBox3.Location = new System.Drawing.Point(29, 598);
+ this.textBox3.Location = new System.Drawing.Point(137, 72);
this.textBox3.Name = "textBox3";
this.textBox3.Size = new System.Drawing.Size(40, 20);
this.textBox3.TabIndex = 66;
//
// textBox4
//
- this.textBox4.Location = new System.Drawing.Point(30, 637);
+ this.textBox4.Location = new System.Drawing.Point(138, 102);
this.textBox4.Name = "textBox4";
this.textBox4.Size = new System.Drawing.Size(39, 20);
this.textBox4.TabIndex = 67;
@@ -957,121 +786,1961 @@ private void InitializeComponent()
// label18
//
this.label18.AutoSize = true;
- this.label18.Location = new System.Drawing.Point(16, 621);
+ this.label18.Location = new System.Drawing.Point(3, 72);
this.label18.Name = "label18";
this.label18.Size = new System.Drawing.Size(63, 13);
this.label18.TabIndex = 68;
this.label18.Text = "Set Position";
//
+ // tabControl1
+ //
+ this.tabControl1.Controls.Add(this.tabPage1);
+ this.tabControl1.Controls.Add(this.tabPage2);
+ this.tabControl1.Controls.Add(this.tabPage3);
+ this.tabControl1.Controls.Add(this.tabPage4);
+ this.tabControl1.Controls.Add(this.tabPage5);
+ this.tabControl1.Location = new System.Drawing.Point(2, 11);
+ this.tabControl1.Name = "tabControl1";
+ this.tabControl1.SelectedIndex = 0;
+ this.tabControl1.Size = new System.Drawing.Size(653, 531);
+ this.tabControl1.TabIndex = 74;
+ //
+ // tabPage1
+ //
+ this.tabPage1.BackColor = System.Drawing.Color.Gray;
+ this.tabPage1.Controls.Add(this.button7);
+ this.tabPage1.Controls.Add(this.groupBox9);
+ this.tabPage1.Controls.Add(this.groupBox8);
+ this.tabPage1.Controls.Add(this.groupBox3);
+ this.tabPage1.Controls.Add(this.groupBox2);
+ this.tabPage1.Controls.Add(this.groupBox1);
+ this.tabPage1.Controls.Add(this.dataGridView1);
+ this.tabPage1.Location = new System.Drawing.Point(4, 22);
+ this.tabPage1.Name = "tabPage1";
+ this.tabPage1.Padding = new System.Windows.Forms.Padding(2);
+ this.tabPage1.Size = new System.Drawing.Size(645, 505);
+ this.tabPage1.TabIndex = 0;
+ this.tabPage1.Text = "Appointment Control";
+ //
+ // button7
+ //
+ this.button7.BackColor = System.Drawing.Color.Gainsboro;
+ this.button7.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.button7.ForeColor = System.Drawing.SystemColors.ControlText;
+ this.button7.Location = new System.Drawing.Point(627, 0);
+ this.button7.Name = "button7";
+ this.button7.Size = new System.Drawing.Size(22, 22);
+ this.button7.TabIndex = 78;
+ this.button7.Text = "?";
+ this.button7.UseVisualStyleBackColor = false;
+ this.button7.Click += new System.EventHandler(this.button7_Click);
+ //
+ // groupBox9
+ //
+ this.groupBox9.BackColor = System.Drawing.Color.Gainsboro;
+ this.groupBox9.Controls.Add(this.btnTest);
+ this.groupBox9.Controls.Add(this.selectDemo);
+ this.groupBox9.Location = new System.Drawing.Point(416, 388);
+ this.groupBox9.Name = "groupBox9";
+ this.groupBox9.Size = new System.Drawing.Size(210, 66);
+ this.groupBox9.TabIndex = 77;
+ this.groupBox9.TabStop = false;
+ //
+ // groupBox8
+ //
+ this.groupBox8.BackColor = System.Drawing.Color.Gainsboro;
+ this.groupBox8.Controls.Add(this.runDiagScriptsButton);
+ this.groupBox8.Controls.Add(this.diagnosticScriptCombo);
+ this.groupBox8.Location = new System.Drawing.Point(339, 127);
+ this.groupBox8.Name = "groupBox8";
+ this.groupBox8.Size = new System.Drawing.Size(287, 71);
+ this.groupBox8.TabIndex = 76;
+ this.groupBox8.TabStop = false;
+ this.groupBox8.Text = "Diagnostic Scripts";
+ //
+ // runDiagScriptsButton
+ //
+ this.runDiagScriptsButton.BackColor = System.Drawing.Color.DarkGray;
+ this.runDiagScriptsButton.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+ this.runDiagScriptsButton.Location = new System.Drawing.Point(197, 19);
+ this.runDiagScriptsButton.Name = "runDiagScriptsButton";
+ this.runDiagScriptsButton.Size = new System.Drawing.Size(75, 24);
+ this.runDiagScriptsButton.TabIndex = 24;
+ this.runDiagScriptsButton.Text = "Run Script";
+ this.runDiagScriptsButton.UseVisualStyleBackColor = false;
+ this.runDiagScriptsButton.Click += new System.EventHandler(this.editDiagScriptsButton_Click);
+ //
+ // diagnosticScriptCombo
+ //
+ this.diagnosticScriptCombo.BackColor = System.Drawing.Color.DarkGray;
+ this.diagnosticScriptCombo.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.diagnosticScriptCombo.FormattingEnabled = true;
+ this.diagnosticScriptCombo.Items.AddRange(new object[] {
+ "Select a Script",
+ "Hit Elevation Lower Limit Switch",
+ "Hit Elevation Upper Limit Switch"});
+ this.diagnosticScriptCombo.Location = new System.Drawing.Point(6, 22);
+ this.diagnosticScriptCombo.Name = "diagnosticScriptCombo";
+ this.diagnosticScriptCombo.Size = new System.Drawing.Size(180, 21);
+ this.diagnosticScriptCombo.TabIndex = 23;
+ this.diagnosticScriptCombo.SelectedIndexChanged += new System.EventHandler(this.diagnosticScriptCombo_SelectedIndexChanged);
+ //
+ // groupBox3
+ //
+ this.groupBox3.BackColor = System.Drawing.Color.Gainsboro;
+ this.groupBox3.Controls.Add(this.textBox3);
+ this.groupBox3.Controls.Add(this.label12);
+ this.groupBox3.Controls.Add(this.textBox2);
+ this.groupBox3.Controls.Add(this.label13);
+ this.groupBox3.Controls.Add(this.textBox4);
+ this.groupBox3.Controls.Add(this.label18);
+ this.groupBox3.Location = new System.Drawing.Point(416, 246);
+ this.groupBox3.Name = "groupBox3";
+ this.groupBox3.Size = new System.Drawing.Size(210, 133);
+ this.groupBox3.TabIndex = 75;
+ this.groupBox3.TabStop = false;
+ this.groupBox3.Text = "Settings";
+ //
+ // groupBox2
+ //
+ this.groupBox2.BackColor = System.Drawing.Color.Gainsboro;
+ this.groupBox2.Controls.Add(this.splitContainer2);
+ this.groupBox2.Location = new System.Drawing.Point(6, 246);
+ this.groupBox2.Name = "groupBox2";
+ this.groupBox2.Size = new System.Drawing.Size(393, 208);
+ this.groupBox2.TabIndex = 74;
+ this.groupBox2.TabStop = false;
+ this.groupBox2.Text = "Encoder Simulation";
+ //
+ // splitContainer2
+ //
+ this.splitContainer2.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
+ this.splitContainer2.Location = new System.Drawing.Point(-6, 19);
+ this.splitContainer2.Name = "splitContainer2";
+ this.splitContainer2.Orientation = System.Windows.Forms.Orientation.Horizontal;
+ //
+ // splitContainer2.Panel1
+ //
+ this.splitContainer2.Panel1.Controls.Add(this.btnAddFiveEncoder);
+ this.splitContainer2.Panel1.Controls.Add(this.lblAbsEncoder);
+ this.splitContainer2.Panel1.Controls.Add(this.txtCustEncoderVal);
+ this.splitContainer2.Panel1.Controls.Add(this.lblEncoderDegrees);
+ this.splitContainer2.Panel1.Controls.Add(this.label9);
+ this.splitContainer2.Panel1.Controls.Add(this.lblAzEncoderDegrees);
+ this.splitContainer2.Panel1.Controls.Add(this.btnSubtractXEncoder);
+ this.splitContainer2.Panel1.Controls.Add(this.lblEncoderTicks);
+ this.splitContainer2.Panel1.Controls.Add(this.btnSubtractFiveEncoder);
+ this.splitContainer2.Panel1.Controls.Add(this.btnSubtractOneEncoder);
+ this.splitContainer2.Panel1.Controls.Add(this.lblAzEncoderTicks);
+ this.splitContainer2.Panel1.Controls.Add(this.btnAddXEncoder);
+ this.splitContainer2.Panel1.Controls.Add(this.btnAddOneEncoder);
+ //
+ // splitContainer2.Panel2
+ //
+ this.splitContainer2.Panel2.Controls.Add(this.label17);
+ this.splitContainer2.Panel2.Controls.Add(this.label14);
+ this.splitContainer2.Panel2.Controls.Add(this.lblElEncoderTicks);
+ this.splitContainer2.Panel2.Controls.Add(this.label16);
+ this.splitContainer2.Panel2.Controls.Add(this.lblElEncoderDegrees);
+ this.splitContainer2.Panel2.Controls.Add(this.button5);
+ this.splitContainer2.Panel2.Controls.Add(this.label10);
+ this.splitContainer2.Panel2.Controls.Add(this.textBox1);
+ this.splitContainer2.Panel2.Controls.Add(this.button2);
+ this.splitContainer2.Panel2.Controls.Add(this.button1);
+ this.splitContainer2.Panel2.Controls.Add(this.button3);
+ this.splitContainer2.Panel2.Controls.Add(this.button6);
+ this.splitContainer2.Panel2.Controls.Add(this.button4);
+ this.splitContainer2.Size = new System.Drawing.Size(410, 191);
+ this.splitContainer2.SplitterDistance = 91;
+ this.splitContainer2.TabIndex = 18;
+ //
+ // groupBox1
+ //
+ this.groupBox1.BackColor = System.Drawing.Color.Gainsboro;
+ this.groupBox1.Controls.Add(this.startTimeTextBox);
+ this.groupBox1.Controls.Add(this.label8);
+ this.groupBox1.Controls.Add(this.statusTextBox);
+ this.groupBox1.Controls.Add(this.endTimeTextBox);
+ this.groupBox1.Controls.Add(this.label7);
+ this.groupBox1.Controls.Add(this.label6);
+ this.groupBox1.Location = new System.Drawing.Point(339, 6);
+ this.groupBox1.Name = "groupBox1";
+ this.groupBox1.Size = new System.Drawing.Size(287, 115);
+ this.groupBox1.TabIndex = 73;
+ this.groupBox1.TabStop = false;
+ this.groupBox1.Text = "Current Appointment";
+ //
+ // tabPage2
+ //
+ this.tabPage2.BackColor = System.Drawing.Color.Gray;
+ this.tabPage2.Controls.Add(this.grpAccelerometerSensorData);
+ this.tabPage2.Controls.Add(this.grpSensorData);
+ this.tabPage2.Controls.Add(this.grpMcuStatus);
+ this.tabPage2.Controls.Add(this.groupBox14);
+ this.tabPage2.Controls.Add(this.grpAbsoluteMotorPositionsTemperatures);
+ this.tabPage2.Controls.Add(this.groupBox5);
+ this.tabPage2.Location = new System.Drawing.Point(4, 22);
+ this.tabPage2.Name = "tabPage2";
+ this.tabPage2.Padding = new System.Windows.Forms.Padding(2);
+ this.tabPage2.Size = new System.Drawing.Size(645, 505);
+ this.tabPage2.TabIndex = 1;
+ this.tabPage2.Text = "Sensor Data";
+ //
+ // grpAccelerometerSensorData
+ //
+ this.grpAccelerometerSensorData.BackColor = System.Drawing.Color.Gainsboro;
+ this.grpAccelerometerSensorData.Controls.Add(this.label26);
+ this.grpAccelerometerSensorData.Controls.Add(this.label25);
+ this.grpAccelerometerSensorData.Controls.Add(this.label45);
+ this.grpAccelerometerSensorData.Controls.Add(this.label38);
+ this.grpAccelerometerSensorData.Controls.Add(this.label46);
+ this.grpAccelerometerSensorData.Controls.Add(this.label48);
+ this.grpAccelerometerSensorData.Controls.Add(this.pnlCounterbalanceAccelerometer);
+ this.grpAccelerometerSensorData.Controls.Add(this.label50);
+ this.grpAccelerometerSensorData.Controls.Add(this.label37);
+ this.grpAccelerometerSensorData.Controls.Add(this.label49);
+ this.grpAccelerometerSensorData.Controls.Add(this.pnlElevationMotorAccelerometer);
+ this.grpAccelerometerSensorData.Controls.Add(this.label47);
+ this.grpAccelerometerSensorData.Controls.Add(this.label36);
+ this.grpAccelerometerSensorData.Controls.Add(this.pnlAzimuthMotorAccelerometer);
+ this.grpAccelerometerSensorData.Location = new System.Drawing.Point(9, 127);
+ this.grpAccelerometerSensorData.Name = "grpAccelerometerSensorData";
+ this.grpAccelerometerSensorData.Size = new System.Drawing.Size(295, 374);
+ this.grpAccelerometerSensorData.TabIndex = 43;
+ this.grpAccelerometerSensorData.TabStop = false;
+ this.grpAccelerometerSensorData.Text = "Accelerometer Sensor Data";
+ //
+ // label26
+ //
+ this.label26.AutoSize = true;
+ this.label26.Location = new System.Drawing.Point(210, 21);
+ this.label26.Name = "label26";
+ this.label26.Size = new System.Drawing.Size(66, 13);
+ this.label26.TabIndex = 102;
+ this.label26.Text = "Acceleration";
+ //
+ // label25
+ //
+ this.label25.ForeColor = System.Drawing.Color.Black;
+ this.label25.Location = new System.Drawing.Point(177, 16);
+ this.label25.Name = "label25";
+ this.label25.Size = new System.Drawing.Size(37, 13);
+ this.label25.TabIndex = 101;
+ this.label25.Text = "__________";
+ //
+ // label45
+ //
+ this.label45.AutoSize = true;
+ this.label45.Location = new System.Drawing.Point(96, 21);
+ this.label45.Name = "label45";
+ this.label45.Size = new System.Drawing.Size(14, 13);
+ this.label45.TabIndex = 52;
+ this.label45.Text = "Y";
+ //
+ // label38
+ //
+ this.label38.AutoSize = true;
+ this.label38.Location = new System.Drawing.Point(2, 263);
+ this.label38.Name = "label38";
+ this.label38.Size = new System.Drawing.Size(153, 13);
+ this.label38.TabIndex = 10;
+ this.label38.Text = "Counterbalance Accelerometer";
+ //
+ // label46
+ //
+ this.label46.ForeColor = System.Drawing.Color.Blue;
+ this.label46.Location = new System.Drawing.Point(2, 16);
+ this.label46.Name = "label46";
+ this.label46.Size = new System.Drawing.Size(37, 13);
+ this.label46.TabIndex = 100;
+ this.label46.Text = "__________";
+ //
+ // label48
+ //
+ this.label48.AutoSize = true;
+ this.label48.Location = new System.Drawing.Point(154, 21);
+ this.label48.Name = "label48";
+ this.label48.Size = new System.Drawing.Size(14, 13);
+ this.label48.TabIndex = 51;
+ this.label48.Text = "Z";
+ //
+ // pnlCounterbalanceAccelerometer
+ //
+ this.pnlCounterbalanceAccelerometer.Controls.Add(this.lblCbDisabled);
+ this.pnlCounterbalanceAccelerometer.Controls.Add(this.counterBalanceAccChart);
+ this.pnlCounterbalanceAccelerometer.Location = new System.Drawing.Point(0, 279);
+ this.pnlCounterbalanceAccelerometer.Name = "pnlCounterbalanceAccelerometer";
+ this.pnlCounterbalanceAccelerometer.Size = new System.Drawing.Size(295, 96);
+ this.pnlCounterbalanceAccelerometer.TabIndex = 4;
+ //
+ // lblCbDisabled
+ //
+ this.lblCbDisabled.AutoSize = true;
+ this.lblCbDisabled.Font = new System.Drawing.Font("Microsoft Sans Serif", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.lblCbDisabled.Location = new System.Drawing.Point(17, 41);
+ this.lblCbDisabled.Name = "lblCbDisabled";
+ this.lblCbDisabled.Size = new System.Drawing.Size(75, 18);
+ this.lblCbDisabled.TabIndex = 33;
+ this.lblCbDisabled.Text = "CB Status";
+ this.lblCbDisabled.Visible = false;
+ //
+ // counterBalanceAccChart
+ //
+ this.counterBalanceAccChart.BackColor = System.Drawing.Color.Gainsboro;
+ chartArea1.AxisX.IsLabelAutoFit = false;
+ chartArea1.AxisX.LabelStyle.Enabled = false;
+ chartArea1.AxisX.MajorGrid.Enabled = false;
+ chartArea1.AxisY.MajorGrid.Enabled = false;
+ chartArea1.BackColor = System.Drawing.Color.Gainsboro;
+ chartArea1.Name = "ChartArea1";
+ this.counterBalanceAccChart.ChartAreas.Add(chartArea1);
+ this.counterBalanceAccChart.Location = new System.Drawing.Point(-20, 0);
+ this.counterBalanceAccChart.Name = "counterBalanceAccChart";
+ series1.ChartArea = "ChartArea1";
+ series1.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line;
+ series1.Color = System.Drawing.Color.Blue;
+ series1.Name = "x";
+ series1.XValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.Int32;
+ series1.YValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.Int32;
+ series2.ChartArea = "ChartArea1";
+ series2.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line;
+ series2.Color = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(192)))), ((int)(((byte)(0)))));
+ series2.Name = "y";
+ series3.ChartArea = "ChartArea1";
+ series3.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line;
+ series3.Color = System.Drawing.Color.Red;
+ series3.Name = "z";
+ series4.ChartArea = "ChartArea1";
+ series4.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line;
+ series4.Color = System.Drawing.Color.Black;
+ series4.Name = "accel";
+ this.counterBalanceAccChart.Series.Add(series1);
+ this.counterBalanceAccChart.Series.Add(series2);
+ this.counterBalanceAccChart.Series.Add(series3);
+ this.counterBalanceAccChart.Series.Add(series4);
+ this.counterBalanceAccChart.Size = new System.Drawing.Size(315, 98);
+ this.counterBalanceAccChart.TabIndex = 0;
+ this.counterBalanceAccChart.Text = "chart1";
+ //
+ // label50
+ //
+ this.label50.ForeColor = System.Drawing.Color.Red;
+ this.label50.Location = new System.Drawing.Point(118, 16);
+ this.label50.Name = "label50";
+ this.label50.Size = new System.Drawing.Size(37, 13);
+ this.label50.TabIndex = 48;
+ this.label50.Text = "__________";
+ //
+ // label37
+ //
+ this.label37.AutoSize = true;
+ this.label37.Location = new System.Drawing.Point(3, 140);
+ this.label37.Name = "label37";
+ this.label37.Size = new System.Drawing.Size(152, 13);
+ this.label37.TabIndex = 10;
+ this.label37.Text = "Elevation Motor Accelerometer";
+ //
+ // label49
+ //
+ this.label49.AutoSize = true;
+ this.label49.Location = new System.Drawing.Point(36, 21);
+ this.label49.Name = "label49";
+ this.label49.Size = new System.Drawing.Size(14, 13);
+ this.label49.TabIndex = 50;
+ this.label49.Text = "X";
+ //
+ // pnlElevationMotorAccelerometer
+ //
+ this.pnlElevationMotorAccelerometer.Controls.Add(this.lblElDisabled);
+ this.pnlElevationMotorAccelerometer.Controls.Add(this.elevationAccChart);
+ this.pnlElevationMotorAccelerometer.Location = new System.Drawing.Point(-3, 156);
+ this.pnlElevationMotorAccelerometer.Name = "pnlElevationMotorAccelerometer";
+ this.pnlElevationMotorAccelerometer.Size = new System.Drawing.Size(298, 98);
+ this.pnlElevationMotorAccelerometer.TabIndex = 2;
+ //
+ // lblElDisabled
+ //
+ this.lblElDisabled.AutoSize = true;
+ this.lblElDisabled.Font = new System.Drawing.Font("Microsoft Sans Serif", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.lblElDisabled.Location = new System.Drawing.Point(20, 43);
+ this.lblElDisabled.Name = "lblElDisabled";
+ this.lblElDisabled.Size = new System.Drawing.Size(72, 18);
+ this.lblElDisabled.TabIndex = 32;
+ this.lblElDisabled.Text = "EL Status";
+ this.lblElDisabled.Visible = false;
+ //
+ // elevationAccChart
+ //
+ this.elevationAccChart.BackColor = System.Drawing.Color.Gainsboro;
+ this.elevationAccChart.BorderlineColor = System.Drawing.Color.Gainsboro;
+ this.elevationAccChart.BorderSkin.PageColor = System.Drawing.Color.Gainsboro;
+ chartArea2.AxisX.IsLabelAutoFit = false;
+ chartArea2.AxisX.LabelStyle.Enabled = false;
+ chartArea2.AxisX.MajorGrid.Enabled = false;
+ chartArea2.AxisY.IsLabelAutoFit = false;
+ chartArea2.AxisY.MajorGrid.Enabled = false;
+ chartArea2.BackColor = System.Drawing.Color.Gainsboro;
+ chartArea2.Name = "ChartArea1";
+ this.elevationAccChart.ChartAreas.Add(chartArea2);
+ this.elevationAccChart.Location = new System.Drawing.Point(-10, 0);
+ this.elevationAccChart.Name = "elevationAccChart";
+ series5.ChartArea = "ChartArea1";
+ series5.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line;
+ series5.Color = System.Drawing.Color.Blue;
+ series5.Name = "x";
+ series5.XValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.Int32;
+ series5.YValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.Int32;
+ series6.ChartArea = "ChartArea1";
+ series6.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line;
+ series6.Color = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(192)))), ((int)(((byte)(0)))));
+ series6.Name = "y";
+ series7.ChartArea = "ChartArea1";
+ series7.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line;
+ series7.Color = System.Drawing.Color.Red;
+ series7.Name = "z";
+ series8.ChartArea = "ChartArea1";
+ series8.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line;
+ series8.Color = System.Drawing.Color.Black;
+ series8.Name = "accel";
+ this.elevationAccChart.Series.Add(series5);
+ this.elevationAccChart.Series.Add(series6);
+ this.elevationAccChart.Series.Add(series7);
+ this.elevationAccChart.Series.Add(series8);
+ this.elevationAccChart.Size = new System.Drawing.Size(308, 101);
+ this.elevationAccChart.TabIndex = 0;
+ this.elevationAccChart.Text = "elevationAccChart";
+ //
+ // label47
+ //
+ this.label47.ForeColor = System.Drawing.Color.Green;
+ this.label47.Location = new System.Drawing.Point(63, 16);
+ this.label47.Name = "label47";
+ this.label47.Size = new System.Drawing.Size(37, 13);
+ this.label47.TabIndex = 49;
+ this.label47.Text = "__________";
+ //
+ // label36
+ //
+ this.label36.AutoSize = true;
+ this.label36.Location = new System.Drawing.Point(3, 34);
+ this.label36.Name = "label36";
+ this.label36.Size = new System.Drawing.Size(145, 13);
+ this.label36.TabIndex = 10;
+ this.label36.Text = "Azimuth Motor Accelerometer";
+ //
+ // pnlAzimuthMotorAccelerometer
+ //
+ this.pnlAzimuthMotorAccelerometer.Controls.Add(this.lblAzDisabled);
+ this.pnlAzimuthMotorAccelerometer.Controls.Add(this.azimuthAccChart);
+ this.pnlAzimuthMotorAccelerometer.Location = new System.Drawing.Point(-4, 50);
+ this.pnlAzimuthMotorAccelerometer.Name = "pnlAzimuthMotorAccelerometer";
+ this.pnlAzimuthMotorAccelerometer.Size = new System.Drawing.Size(299, 86);
+ this.pnlAzimuthMotorAccelerometer.TabIndex = 0;
+ //
+ // lblAzDisabled
+ //
+ this.lblAzDisabled.AutoSize = true;
+ this.lblAzDisabled.Font = new System.Drawing.Font("Microsoft Sans Serif", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.lblAzDisabled.Location = new System.Drawing.Point(21, 35);
+ this.lblAzDisabled.Name = "lblAzDisabled";
+ this.lblAzDisabled.Size = new System.Drawing.Size(72, 18);
+ this.lblAzDisabled.TabIndex = 31;
+ this.lblAzDisabled.Text = "AZ Status";
+ this.lblAzDisabled.Visible = false;
+ //
+ // azimuthAccChart
+ //
+ this.azimuthAccChart.BackColor = System.Drawing.Color.Gainsboro;
+ this.azimuthAccChart.BorderlineColor = System.Drawing.Color.Gainsboro;
+ chartArea3.AxisX.IsLabelAutoFit = false;
+ chartArea3.AxisX.LabelStyle.Enabled = false;
+ chartArea3.AxisX.MajorGrid.Enabled = false;
+ chartArea3.AxisY.IsLabelAutoFit = false;
+ chartArea3.AxisY.MajorGrid.Enabled = false;
+ chartArea3.BackColor = System.Drawing.Color.Gainsboro;
+ chartArea3.Name = "ChartArea1";
+ this.azimuthAccChart.ChartAreas.Add(chartArea3);
+ this.azimuthAccChart.Location = new System.Drawing.Point(-9, 0);
+ this.azimuthAccChart.Name = "azimuthAccChart";
+ series9.ChartArea = "ChartArea1";
+ series9.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line;
+ series9.Color = System.Drawing.Color.Blue;
+ series9.Name = "x";
+ series9.XValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.Int32;
+ series9.YValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.Int32;
+ series10.ChartArea = "ChartArea1";
+ series10.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line;
+ series10.Color = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(192)))), ((int)(((byte)(0)))));
+ series10.Name = "y";
+ series11.ChartArea = "ChartArea1";
+ series11.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line;
+ series11.Color = System.Drawing.Color.Red;
+ series11.Name = "z";
+ series12.ChartArea = "ChartArea1";
+ series12.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line;
+ series12.Color = System.Drawing.Color.Black;
+ series12.Name = "accel";
+ this.azimuthAccChart.Series.Add(series9);
+ this.azimuthAccChart.Series.Add(series10);
+ this.azimuthAccChart.Series.Add(series11);
+ this.azimuthAccChart.Series.Add(series12);
+ this.azimuthAccChart.Size = new System.Drawing.Size(308, 86);
+ this.azimuthAccChart.TabIndex = 0;
+ this.azimuthAccChart.Text = "chart1";
+ //
+ // grpSensorData
+ //
+ this.grpSensorData.BackColor = System.Drawing.Color.Gainsboro;
+ this.grpSensorData.Controls.Add(this.lbGateStat);
+ this.grpSensorData.Controls.Add(this.lbEstopStat);
+ this.grpSensorData.Controls.Add(this.label31);
+ this.grpSensorData.Controls.Add(this.label30);
+ this.grpSensorData.Controls.Add(this.lblAzHome1);
+ this.grpSensorData.Controls.Add(this.lblElLimStatus2);
+ this.grpSensorData.Controls.Add(this.lblElLimStatus1);
+ this.grpSensorData.Controls.Add(this.lblElHome);
+ this.grpSensorData.Controls.Add(this.lblELHomeStatus);
+ this.grpSensorData.Controls.Add(this.lblAzHomeStatus1);
+ this.grpSensorData.Controls.Add(this.lblAzLimit1);
+ this.grpSensorData.Controls.Add(this.lblAzLimit2);
+ this.grpSensorData.Location = new System.Drawing.Point(9, 4);
+ this.grpSensorData.Name = "grpSensorData";
+ this.grpSensorData.Size = new System.Drawing.Size(295, 117);
+ this.grpSensorData.TabIndex = 42;
+ this.grpSensorData.TabStop = false;
+ this.grpSensorData.Text = "Sensor Data";
+ //
+ // lbGateStat
+ //
+ this.lbGateStat.AutoSize = true;
+ this.lbGateStat.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.lbGateStat.Location = new System.Drawing.Point(220, 93);
+ this.lbGateStat.Name = "lbGateStat";
+ this.lbGateStat.Size = new System.Drawing.Size(56, 15);
+ this.lbGateStat.TabIndex = 21;
+ this.lbGateStat.Text = "Inactive";
+ //
+ // lbEstopStat
+ //
+ this.lbEstopStat.AutoSize = true;
+ this.lbEstopStat.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.lbEstopStat.Location = new System.Drawing.Point(220, 78);
+ this.lbEstopStat.Name = "lbEstopStat";
+ this.lbEstopStat.Size = new System.Drawing.Size(56, 15);
+ this.lbEstopStat.TabIndex = 20;
+ this.lbEstopStat.Text = "Inactive";
+ //
+ // label31
+ //
+ this.label31.AutoSize = true;
+ this.label31.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.label31.Location = new System.Drawing.Point(6, 93);
+ this.label31.Name = "label31";
+ this.label31.Size = new System.Drawing.Size(44, 15);
+ this.label31.TabIndex = 19;
+ this.label31.Text = "Gates";
+ //
+ // label30
+ //
+ this.label30.AutoSize = true;
+ this.label30.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.label30.Location = new System.Drawing.Point(6, 78);
+ this.label30.Name = "label30";
+ this.label30.Size = new System.Drawing.Size(43, 15);
+ this.label30.TabIndex = 18;
+ this.label30.Text = "Estop";
+ //
+ // lblAzHome1
+ //
+ this.lblAzHome1.AutoSize = true;
+ this.lblAzHome1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.lblAzHome1.Location = new System.Drawing.Point(6, 16);
+ this.lblAzHome1.Name = "lblAzHome1";
+ this.lblAzHome1.Size = new System.Drawing.Size(149, 15);
+ this.lblAzHome1.TabIndex = 0;
+ this.lblAzHome1.Text = "Azimuth Home Sensor";
+ //
+ // lblElLimStatus2
+ //
+ this.lblElLimStatus2.AutoSize = true;
+ this.lblElLimStatus2.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.lblElLimStatus2.Location = new System.Drawing.Point(220, 63);
+ this.lblElLimStatus2.Name = "lblElLimStatus2";
+ this.lblElLimStatus2.Size = new System.Drawing.Size(56, 15);
+ this.lblElLimStatus2.TabIndex = 15;
+ this.lblElLimStatus2.Text = "Inactive";
+ //
+ // lblElLimStatus1
+ //
+ this.lblElLimStatus1.AutoSize = true;
+ this.lblElLimStatus1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.lblElLimStatus1.Location = new System.Drawing.Point(220, 48);
+ this.lblElLimStatus1.Name = "lblElLimStatus1";
+ this.lblElLimStatus1.Size = new System.Drawing.Size(56, 15);
+ this.lblElLimStatus1.TabIndex = 14;
+ this.lblElLimStatus1.Text = "Inactive";
+ //
+ // lblElHome
+ //
+ this.lblElHome.AutoSize = true;
+ this.lblElHome.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.lblElHome.Location = new System.Drawing.Point(6, 31);
+ this.lblElHome.Name = "lblElHome";
+ this.lblElHome.Size = new System.Drawing.Size(157, 15);
+ this.lblElHome.TabIndex = 2;
+ this.lblElHome.Text = "Elevation Home Sensor";
+ //
+ // lblELHomeStatus
+ //
+ this.lblELHomeStatus.AutoSize = true;
+ this.lblELHomeStatus.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.lblELHomeStatus.Location = new System.Drawing.Point(220, 31);
+ this.lblELHomeStatus.Name = "lblELHomeStatus";
+ this.lblELHomeStatus.Size = new System.Drawing.Size(56, 15);
+ this.lblELHomeStatus.TabIndex = 5;
+ this.lblELHomeStatus.Text = "Inactive";
+ //
+ // lblAzHomeStatus1
+ //
+ this.lblAzHomeStatus1.AutoSize = true;
+ this.lblAzHomeStatus1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.lblAzHomeStatus1.Location = new System.Drawing.Point(220, 16);
+ this.lblAzHomeStatus1.Name = "lblAzHomeStatus1";
+ this.lblAzHomeStatus1.Size = new System.Drawing.Size(56, 15);
+ this.lblAzHomeStatus1.TabIndex = 3;
+ this.lblAzHomeStatus1.Text = "Inactive";
+ //
+ // lblAzLimit1
+ //
+ this.lblAzLimit1.AutoSize = true;
+ this.lblAzLimit1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.lblAzLimit1.Location = new System.Drawing.Point(6, 48);
+ this.lblAzLimit1.Name = "lblAzLimit1";
+ this.lblAzLimit1.Size = new System.Drawing.Size(160, 15);
+ this.lblAzLimit1.TabIndex = 10;
+ this.lblAzLimit1.Text = "Elevation Limit Switch 1";
+ //
+ // lblAzLimit2
+ //
+ this.lblAzLimit2.AutoSize = true;
+ this.lblAzLimit2.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.lblAzLimit2.Location = new System.Drawing.Point(6, 63);
+ this.lblAzLimit2.Name = "lblAzLimit2";
+ this.lblAzLimit2.Size = new System.Drawing.Size(160, 15);
+ this.lblAzLimit2.TabIndex = 11;
+ this.lblAzLimit2.Text = "Elevation Limit Switch 2";
+ //
+ // grpMcuStatus
+ //
+ this.grpMcuStatus.BackColor = System.Drawing.Color.Gainsboro;
+ this.grpMcuStatus.Controls.Add(this.lblMCUStatus);
+ this.grpMcuStatus.Controls.Add(this.lblMCUStatusText);
+ this.grpMcuStatus.Controls.Add(this.lblMCUErrors);
+ this.grpMcuStatus.Controls.Add(this.btnResetMcuErrors);
+ this.grpMcuStatus.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.grpMcuStatus.Location = new System.Drawing.Point(314, 394);
+ this.grpMcuStatus.Margin = new System.Windows.Forms.Padding(2);
+ this.grpMcuStatus.Name = "grpMcuStatus";
+ this.grpMcuStatus.Padding = new System.Windows.Forms.Padding(2);
+ this.grpMcuStatus.Size = new System.Drawing.Size(324, 106);
+ this.grpMcuStatus.TabIndex = 38;
+ this.grpMcuStatus.TabStop = false;
+ this.grpMcuStatus.Text = "Motor Controller Status";
+ //
+ // lblMCUStatus
+ //
+ this.lblMCUStatus.AutoSize = true;
+ this.lblMCUStatus.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.lblMCUStatus.ForeColor = System.Drawing.Color.Black;
+ this.lblMCUStatus.Location = new System.Drawing.Point(95, 81);
+ this.lblMCUStatus.Name = "lblMCUStatus";
+ this.lblMCUStatus.Size = new System.Drawing.Size(34, 16);
+ this.lblMCUStatus.TabIndex = 76;
+ this.lblMCUStatus.Text = "N/A";
+ //
+ // lblMCUStatusText
+ //
+ this.lblMCUStatusText.AutoSize = true;
+ this.lblMCUStatusText.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.lblMCUStatusText.Location = new System.Drawing.Point(6, 81);
+ this.lblMCUStatusText.Name = "lblMCUStatusText";
+ this.lblMCUStatusText.Size = new System.Drawing.Size(92, 16);
+ this.lblMCUStatusText.TabIndex = 33;
+ this.lblMCUStatusText.Text = "MCU Status:";
+ //
+ // lblMCUErrors
+ //
+ this.lblMCUErrors.AutoSize = true;
+ this.lblMCUErrors.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.lblMCUErrors.Location = new System.Drawing.Point(17, 24);
+ this.lblMCUErrors.Name = "lblMCUErrors";
+ this.lblMCUErrors.Size = new System.Drawing.Size(0, 13);
+ this.lblMCUErrors.TabIndex = 75;
+ //
+ // btnResetMcuErrors
+ //
+ this.btnResetMcuErrors.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.btnResetMcuErrors.Location = new System.Drawing.Point(210, 78);
+ this.btnResetMcuErrors.Name = "btnResetMcuErrors";
+ this.btnResetMcuErrors.Size = new System.Drawing.Size(110, 23);
+ this.btnResetMcuErrors.TabIndex = 0;
+ this.btnResetMcuErrors.Text = "Reset MCU Errors";
+ this.btnResetMcuErrors.UseVisualStyleBackColor = true;
+ this.btnResetMcuErrors.Click += new System.EventHandler(this.btnResetMcuErrors_Click);
+ //
+ // groupBox14
+ //
+ this.groupBox14.BackColor = System.Drawing.Color.Gainsboro;
+ this.groupBox14.Controls.Add(this.farTempConvert);
+ this.groupBox14.Controls.Add(this.celTempConvert);
+ this.groupBox14.Location = new System.Drawing.Point(314, 19);
+ this.groupBox14.Name = "groupBox14";
+ this.groupBox14.Size = new System.Drawing.Size(324, 54);
+ this.groupBox14.TabIndex = 39;
+ this.groupBox14.TabStop = false;
+ this.groupBox14.Text = "Temperature Conversion";
+ //
+ // farTempConvert
+ //
+ this.farTempConvert.BackColor = System.Drawing.Color.Silver;
+ this.farTempConvert.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
+ this.farTempConvert.Location = new System.Drawing.Point(183, 19);
+ this.farTempConvert.Name = "farTempConvert";
+ this.farTempConvert.Size = new System.Drawing.Size(130, 23);
+ this.farTempConvert.TabIndex = 1;
+ this.farTempConvert.Text = "Fahrenheit";
+ this.farTempConvert.TextImageRelation = System.Windows.Forms.TextImageRelation.TextBeforeImage;
+ this.farTempConvert.UseVisualStyleBackColor = false;
+ this.farTempConvert.Click += new System.EventHandler(this.farTempConvert_Click);
+ //
+ // celTempConvert
+ //
+ this.celTempConvert.BackColor = System.Drawing.Color.Silver;
+ this.celTempConvert.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
+ this.celTempConvert.Location = new System.Drawing.Point(9, 19);
+ this.celTempConvert.Name = "celTempConvert";
+ this.celTempConvert.Size = new System.Drawing.Size(130, 23);
+ this.celTempConvert.TabIndex = 0;
+ this.celTempConvert.Text = "Celsius";
+ this.celTempConvert.UseVisualStyleBackColor = false;
+ this.celTempConvert.Click += new System.EventHandler(this.celTempConvert_Click);
+ //
+ // grpAbsoluteMotorPositionsTemperatures
+ //
+ this.grpAbsoluteMotorPositionsTemperatures.BackColor = System.Drawing.Color.Gainsboro;
+ this.grpAbsoluteMotorPositionsTemperatures.Controls.Add(this.splitContainer1);
+ this.grpAbsoluteMotorPositionsTemperatures.Location = new System.Drawing.Point(314, 267);
+ this.grpAbsoluteMotorPositionsTemperatures.Margin = new System.Windows.Forms.Padding(2);
+ this.grpAbsoluteMotorPositionsTemperatures.Name = "grpAbsoluteMotorPositionsTemperatures";
+ this.grpAbsoluteMotorPositionsTemperatures.Padding = new System.Windows.Forms.Padding(2);
+ this.grpAbsoluteMotorPositionsTemperatures.Size = new System.Drawing.Size(324, 123);
+ this.grpAbsoluteMotorPositionsTemperatures.TabIndex = 38;
+ this.grpAbsoluteMotorPositionsTemperatures.TabStop = false;
+ this.grpAbsoluteMotorPositionsTemperatures.Text = "Absolute Motor Positions and Temperatures";
+ //
+ // splitContainer1
+ //
+ this.splitContainer1.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
+ this.splitContainer1.Location = new System.Drawing.Point(-7, 18);
+ this.splitContainer1.Name = "splitContainer1";
+ this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal;
+ //
+ // splitContainer1.Panel1
+ //
+ this.splitContainer1.Panel1.Controls.Add(this.label32);
+ this.splitContainer1.Panel1.Controls.Add(this.label34);
+ this.splitContainer1.Panel1.Controls.Add(this.lblCurrentAzOrientation);
+ this.splitContainer1.Panel1.Controls.Add(this.lblCurrentElOrientation);
+ this.splitContainer1.Panel1.Controls.Add(this.lblElAbsPos);
+ this.splitContainer1.Panel1.Controls.Add(this.lblAzAbsPos);
+ //
+ // splitContainer1.Panel2
+ //
+ this.splitContainer1.Panel2.Controls.Add(this.AZTempUnitLabel);
+ this.splitContainer1.Panel2.Controls.Add(this.ElTempUnitLabel);
+ this.splitContainer1.Panel2.Controls.Add(this.lblAzimuthTemp);
+ this.splitContainer1.Panel2.Controls.Add(this.fldElTemp);
+ this.splitContainer1.Panel2.Controls.Add(this.fldAzTemp);
+ this.splitContainer1.Panel2.Controls.Add(this.lblElevationTemp);
+ this.splitContainer1.Size = new System.Drawing.Size(333, 123);
+ this.splitContainer1.SplitterDistance = 48;
+ this.splitContainer1.TabIndex = 20;
+ //
+ // label32
+ //
+ this.label32.AutoSize = true;
+ this.label32.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.label32.Location = new System.Drawing.Point(257, 27);
+ this.label32.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
+ this.label32.Name = "label32";
+ this.label32.Size = new System.Drawing.Size(47, 13);
+ this.label32.TabIndex = 27;
+ this.label32.Text = "Degrees";
+ //
+ // label34
+ //
+ this.label34.AutoSize = true;
+ this.label34.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.label34.Location = new System.Drawing.Point(257, 10);
+ this.label34.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
+ this.label34.Name = "label34";
+ this.label34.Size = new System.Drawing.Size(47, 13);
+ this.label34.TabIndex = 26;
+ this.label34.Text = "Degrees";
+ //
+ // lblCurrentAzOrientation
+ //
+ this.lblCurrentAzOrientation.AutoSize = true;
+ this.lblCurrentAzOrientation.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.lblCurrentAzOrientation.Location = new System.Drawing.Point(10, 7);
+ this.lblCurrentAzOrientation.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
+ this.lblCurrentAzOrientation.Name = "lblCurrentAzOrientation";
+ this.lblCurrentAzOrientation.Size = new System.Drawing.Size(129, 16);
+ this.lblCurrentAzOrientation.TabIndex = 7;
+ this.lblCurrentAzOrientation.Text = "Azimuth Position: ";
+ //
+ // lblCurrentElOrientation
+ //
+ this.lblCurrentElOrientation.AutoSize = true;
+ this.lblCurrentElOrientation.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.lblCurrentElOrientation.Location = new System.Drawing.Point(9, 25);
+ this.lblCurrentElOrientation.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
+ this.lblCurrentElOrientation.Name = "lblCurrentElOrientation";
+ this.lblCurrentElOrientation.Size = new System.Drawing.Size(141, 16);
+ this.lblCurrentElOrientation.TabIndex = 8;
+ this.lblCurrentElOrientation.Text = "Elevation Position: ";
+ //
+ // lblElAbsPos
+ //
+ this.lblElAbsPos.AutoSize = true;
+ this.lblElAbsPos.Font = new System.Drawing.Font("Microsoft Sans Serif", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.lblElAbsPos.Location = new System.Drawing.Point(198, 27);
+ this.lblElAbsPos.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
+ this.lblElAbsPos.Name = "lblElAbsPos";
+ this.lblElAbsPos.Size = new System.Drawing.Size(28, 18);
+ this.lblElAbsPos.TabIndex = 10;
+ this.lblElAbsPos.Text = "0.0";
+ //
+ // lblAzAbsPos
+ //
+ this.lblAzAbsPos.AutoSize = true;
+ this.lblAzAbsPos.Font = new System.Drawing.Font("Microsoft Sans Serif", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.lblAzAbsPos.Location = new System.Drawing.Point(198, 6);
+ this.lblAzAbsPos.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
+ this.lblAzAbsPos.Name = "lblAzAbsPos";
+ this.lblAzAbsPos.Size = new System.Drawing.Size(28, 18);
+ this.lblAzAbsPos.TabIndex = 9;
+ this.lblAzAbsPos.Text = "0.0";
+ //
+ // AZTempUnitLabel
+ //
+ this.AZTempUnitLabel.AutoSize = true;
+ this.AZTempUnitLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.AZTempUnitLabel.Location = new System.Drawing.Point(257, 12);
+ this.AZTempUnitLabel.Name = "AZTempUnitLabel";
+ this.AZTempUnitLabel.Size = new System.Drawing.Size(57, 13);
+ this.AZTempUnitLabel.TabIndex = 32;
+ this.AZTempUnitLabel.Text = "Fahrenheit";
+ //
+ // ElTempUnitLabel
+ //
+ this.ElTempUnitLabel.AutoSize = true;
+ this.ElTempUnitLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.ElTempUnitLabel.Location = new System.Drawing.Point(257, 33);
+ this.ElTempUnitLabel.Name = "ElTempUnitLabel";
+ this.ElTempUnitLabel.Size = new System.Drawing.Size(57, 13);
+ this.ElTempUnitLabel.TabIndex = 31;
+ this.ElTempUnitLabel.Text = "Fahrenheit";
+ //
+ // groupBox5
+ //
+ this.groupBox5.BackColor = System.Drawing.Color.Gainsboro;
+ this.groupBox5.Controls.Add(this.InsideTempUnits);
+ this.groupBox5.Controls.Add(this.rainRateUnits);
+ this.groupBox5.Controls.Add(this.pressUnits);
+ this.groupBox5.Controls.Add(this.dailyRainfallUnits);
+ this.groupBox5.Controls.Add(this.outTempUnits);
+ this.groupBox5.Controls.Add(this.label35);
+ this.groupBox5.Controls.Add(this.windSpeedUnits);
+ this.groupBox5.Controls.Add(this.insideTempLabel);
+ this.groupBox5.Controls.Add(this.label23);
+ this.groupBox5.Controls.Add(this.rainRateLabel);
+ this.groupBox5.Controls.Add(this.barometricPressureLabel);
+ this.groupBox5.Controls.Add(this.dailyRainfallLabel);
+ this.groupBox5.Controls.Add(this.outsideTempLabel);
+ this.groupBox5.Controls.Add(this.label19);
+ this.groupBox5.Controls.Add(this.label20);
+ this.groupBox5.Controls.Add(this.label1);
+ this.groupBox5.Controls.Add(this.label2);
+ this.groupBox5.Controls.Add(this.label5);
+ this.groupBox5.Controls.Add(this.windDirLabel);
+ this.groupBox5.Controls.Add(this.label11);
+ this.groupBox5.Controls.Add(this.windSpeedLabel);
+ this.groupBox5.Location = new System.Drawing.Point(314, 78);
+ this.groupBox5.Margin = new System.Windows.Forms.Padding(2);
+ this.groupBox5.Name = "groupBox5";
+ this.groupBox5.Padding = new System.Windows.Forms.Padding(2);
+ this.groupBox5.Size = new System.Drawing.Size(324, 185);
+ this.groupBox5.TabIndex = 37;
+ this.groupBox5.TabStop = false;
+ this.groupBox5.Text = "Weather Sensor Data";
+ //
+ // InsideTempUnits
+ //
+ this.InsideTempUnits.AutoSize = true;
+ this.InsideTempUnits.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.InsideTempUnits.Location = new System.Drawing.Point(257, 117);
+ this.InsideTempUnits.Name = "InsideTempUnits";
+ this.InsideTempUnits.Size = new System.Drawing.Size(57, 13);
+ this.InsideTempUnits.TabIndex = 30;
+ this.InsideTempUnits.Text = "Fahrenheit";
+ //
+ // rainRateUnits
+ //
+ this.rainRateUnits.AutoSize = true;
+ this.rainRateUnits.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.rainRateUnits.Location = new System.Drawing.Point(257, 91);
+ this.rainRateUnits.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
+ this.rainRateUnits.Name = "rainRateUnits";
+ this.rainRateUnits.Size = new System.Drawing.Size(39, 13);
+ this.rainRateUnits.TabIndex = 27;
+ this.rainRateUnits.Text = "Inches";
+ //
+ // pressUnits
+ //
+ this.pressUnits.AutoSize = true;
+ this.pressUnits.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.pressUnits.Location = new System.Drawing.Point(257, 164);
+ this.pressUnits.Name = "pressUnits";
+ this.pressUnits.Size = new System.Drawing.Size(58, 13);
+ this.pressUnits.TabIndex = 29;
+ this.pressUnits.Text = "Inches/Hg";
+ //
+ // dailyRainfallUnits
+ //
+ this.dailyRainfallUnits.AutoSize = true;
+ this.dailyRainfallUnits.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.dailyRainfallUnits.Location = new System.Drawing.Point(257, 70);
+ this.dailyRainfallUnits.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
+ this.dailyRainfallUnits.Name = "dailyRainfallUnits";
+ this.dailyRainfallUnits.Size = new System.Drawing.Size(63, 13);
+ this.dailyRainfallUnits.TabIndex = 26;
+ this.dailyRainfallUnits.Text = "Inches/Day";
+ //
+ // outTempUnits
+ //
+ this.outTempUnits.AutoSize = true;
+ this.outTempUnits.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.outTempUnits.Location = new System.Drawing.Point(257, 139);
+ this.outTempUnits.Name = "outTempUnits";
+ this.outTempUnits.Size = new System.Drawing.Size(57, 13);
+ this.outTempUnits.TabIndex = 28;
+ this.outTempUnits.Text = "Fahrenheit";
+ //
+ // label35
+ //
+ this.label35.AutoSize = true;
+ this.label35.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.label35.Location = new System.Drawing.Point(256, 20);
+ this.label35.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
+ this.label35.Name = "label35";
+ this.label35.Size = new System.Drawing.Size(23, 20);
+ this.label35.TabIndex = 25;
+ this.label35.Text = " --";
+ //
+ // windSpeedUnits
+ //
+ this.windSpeedUnits.AutoSize = true;
+ this.windSpeedUnits.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.windSpeedUnits.Location = new System.Drawing.Point(257, 48);
+ this.windSpeedUnits.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
+ this.windSpeedUnits.Name = "windSpeedUnits";
+ this.windSpeedUnits.Size = new System.Drawing.Size(31, 13);
+ this.windSpeedUnits.TabIndex = 24;
+ this.windSpeedUnits.Text = "MPH";
+ //
+ // insideTempLabel
+ //
+ this.insideTempLabel.AutoSize = true;
+ this.insideTempLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.insideTempLabel.Location = new System.Drawing.Point(202, 115);
+ this.insideTempLabel.Name = "insideTempLabel";
+ this.insideTempLabel.Size = new System.Drawing.Size(22, 18);
+ this.insideTempLabel.TabIndex = 23;
+ this.insideTempLabel.Text = " --";
+ //
+ // label23
+ //
+ this.label23.AutoSize = true;
+ this.label23.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.label23.Location = new System.Drawing.Point(6, 115);
+ this.label23.Name = "label23";
+ this.label23.Size = new System.Drawing.Size(136, 15);
+ this.label23.TabIndex = 22;
+ this.label23.Text = "Inside Temperature ";
+ //
+ // rainRateLabel
+ //
+ this.rainRateLabel.AutoSize = true;
+ this.rainRateLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.rainRateLabel.Location = new System.Drawing.Point(203, 91);
+ this.rainRateLabel.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
+ this.rainRateLabel.Name = "rainRateLabel";
+ this.rainRateLabel.Size = new System.Drawing.Size(22, 18);
+ this.rainRateLabel.TabIndex = 19;
+ this.rainRateLabel.Text = " --";
+ //
+ // barometricPressureLabel
+ //
+ this.barometricPressureLabel.AutoSize = true;
+ this.barometricPressureLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.barometricPressureLabel.Location = new System.Drawing.Point(203, 159);
+ this.barometricPressureLabel.Name = "barometricPressureLabel";
+ this.barometricPressureLabel.Size = new System.Drawing.Size(22, 18);
+ this.barometricPressureLabel.TabIndex = 21;
+ this.barometricPressureLabel.Text = " --";
+ //
+ // dailyRainfallLabel
+ //
+ this.dailyRainfallLabel.AutoSize = true;
+ this.dailyRainfallLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.dailyRainfallLabel.Location = new System.Drawing.Point(203, 68);
+ this.dailyRainfallLabel.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
+ this.dailyRainfallLabel.Name = "dailyRainfallLabel";
+ this.dailyRainfallLabel.Size = new System.Drawing.Size(22, 18);
+ this.dailyRainfallLabel.TabIndex = 18;
+ this.dailyRainfallLabel.Text = " --";
+ //
+ // outsideTempLabel
+ //
+ this.outsideTempLabel.AutoSize = true;
+ this.outsideTempLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.outsideTempLabel.Location = new System.Drawing.Point(202, 139);
+ this.outsideTempLabel.Name = "outsideTempLabel";
+ this.outsideTempLabel.Size = new System.Drawing.Size(22, 18);
+ this.outsideTempLabel.TabIndex = 20;
+ this.outsideTempLabel.Text = " --";
+ //
// label19
//
this.label19.AutoSize = true;
- this.label19.Location = new System.Drawing.Point(163, 341);
+ this.label19.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.label19.Location = new System.Drawing.Point(5, 164);
this.label19.Name = "label19";
- this.label19.Size = new System.Drawing.Size(98, 13);
- this.label19.TabIndex = 69;
- this.label19.Text = "Encoder Simulation";
+ this.label19.Size = new System.Drawing.Size(142, 15);
+ this.label19.TabIndex = 19;
+ this.label19.Text = "Barometric Pressure ";
+ //
+ // label20
+ //
+ this.label20.AutoSize = true;
+ this.label20.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.label20.Location = new System.Drawing.Point(6, 142);
+ this.label20.Name = "label20";
+ this.label20.Size = new System.Drawing.Size(146, 15);
+ this.label20.TabIndex = 18;
+ this.label20.Text = "Outside Temperature ";
+ //
+ // label1
+ //
+ this.label1.AutoSize = true;
+ this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.label1.Location = new System.Drawing.Point(6, 91);
+ this.label1.Name = "label1";
+ this.label1.Size = new System.Drawing.Size(75, 15);
+ this.label1.TabIndex = 17;
+ this.label1.Text = "Rain Rate ";
+ //
+ // label2
+ //
+ this.label2.AutoSize = true;
+ this.label2.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.label2.Location = new System.Drawing.Point(5, 68);
+ this.label2.Name = "label2";
+ this.label2.Size = new System.Drawing.Size(97, 15);
+ this.label2.TabIndex = 16;
+ this.label2.Text = "Daily Rainfall ";
+ //
+ // label5
+ //
+ this.label5.AutoSize = true;
+ this.label5.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.label5.Location = new System.Drawing.Point(4, 46);
+ this.label5.Name = "label5";
+ this.label5.Size = new System.Drawing.Size(84, 15);
+ this.label5.TabIndex = 14;
+ this.label5.Text = "Wind Speed";
+ //
+ // label11
+ //
+ this.label11.AutoSize = true;
+ this.label11.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.label11.Location = new System.Drawing.Point(4, 25);
+ this.label11.Name = "label11";
+ this.label11.Size = new System.Drawing.Size(105, 15);
+ this.label11.TabIndex = 15;
+ this.label11.Text = "Wind Direction:";
+ //
+ // tabPage3
+ //
+ this.tabPage3.BackColor = System.Drawing.Color.Gray;
+ this.tabPage3.Controls.Add(this.Encoders);
+ this.tabPage3.Controls.Add(this.SensorNetworkSensorInitialization);
+ this.tabPage3.Controls.Add(this.SoftwareStopsThresholdGroup);
+ this.tabPage3.Controls.Add(this.grpProximitySensors);
+ this.tabPage3.Controls.Add(this.MotorTemperatureSensors);
+ this.tabPage3.Controls.Add(this.GatesSensors);
+ this.tabPage3.Controls.Add(this.Accelerometers);
+ this.tabPage3.Controls.Add(this.WeatherStation);
+ this.tabPage3.Location = new System.Drawing.Point(4, 22);
+ this.tabPage3.Name = "tabPage3";
+ this.tabPage3.Padding = new System.Windows.Forms.Padding(2);
+ this.tabPage3.Size = new System.Drawing.Size(645, 505);
+ this.tabPage3.TabIndex = 2;
+ this.tabPage3.Text = "Sensor Overrides/Init";
+ //
+ // Encoders
+ //
+ this.Encoders.BackColor = System.Drawing.Color.Gainsboro;
+ this.Encoders.Controls.Add(this.ElecationAbsoluteEncoder_lbl);
+ this.Encoders.Controls.Add(this.btnElevationAbsoluteEncoder);
+ this.Encoders.Controls.Add(this.btnAzimuthAbsoluteEncoder);
+ this.Encoders.Controls.Add(this.AzimuthAbsoluteEncoder_lbl);
+ this.Encoders.Location = new System.Drawing.Point(3, 380);
+ this.Encoders.Name = "Encoders";
+ this.Encoders.Padding = new System.Windows.Forms.Padding(2);
+ this.Encoders.Size = new System.Drawing.Size(338, 120);
+ this.Encoders.TabIndex = 16;
+ this.Encoders.TabStop = false;
+ this.Encoders.Text = "Encoders";
+ //
+ // ElecationAbsoluteEncoder_lbl
+ //
+ this.ElecationAbsoluteEncoder_lbl.AutoSize = true;
+ this.ElecationAbsoluteEncoder_lbl.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.ElecationAbsoluteEncoder_lbl.Location = new System.Drawing.Point(9, 69);
+ this.ElecationAbsoluteEncoder_lbl.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
+ this.ElecationAbsoluteEncoder_lbl.Name = "ElecationAbsoluteEncoder_lbl";
+ this.ElecationAbsoluteEncoder_lbl.Size = new System.Drawing.Size(164, 13);
+ this.ElecationAbsoluteEncoder_lbl.TabIndex = 10;
+ this.ElecationAbsoluteEncoder_lbl.Text = "Elevation Absolute Encoder";
+ //
+ // btnElevationAbsoluteEncoder
+ //
+ this.btnElevationAbsoluteEncoder.BackColor = System.Drawing.Color.Yellow;
+ this.btnElevationAbsoluteEncoder.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+ this.btnElevationAbsoluteEncoder.Location = new System.Drawing.Point(228, 64);
+ this.btnElevationAbsoluteEncoder.Name = "btnElevationAbsoluteEncoder";
+ this.btnElevationAbsoluteEncoder.Size = new System.Drawing.Size(89, 23);
+ this.btnElevationAbsoluteEncoder.TabIndex = 14;
+ this.btnElevationAbsoluteEncoder.Text = "NOT LOADED";
+ this.btnElevationAbsoluteEncoder.UseVisualStyleBackColor = false;
+ this.btnElevationAbsoluteEncoder.Click += new System.EventHandler(this.btnElevationAbsoluteEncoder_Click);
+ //
+ // btnAzimuthAbsoluteEncoder
+ //
+ this.btnAzimuthAbsoluteEncoder.BackColor = System.Drawing.Color.Yellow;
+ this.btnAzimuthAbsoluteEncoder.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+ this.btnAzimuthAbsoluteEncoder.Location = new System.Drawing.Point(228, 31);
+ this.btnAzimuthAbsoluteEncoder.Name = "btnAzimuthAbsoluteEncoder";
+ this.btnAzimuthAbsoluteEncoder.Size = new System.Drawing.Size(89, 23);
+ this.btnAzimuthAbsoluteEncoder.TabIndex = 13;
+ this.btnAzimuthAbsoluteEncoder.Text = "NOT LOADED";
+ this.btnAzimuthAbsoluteEncoder.UseVisualStyleBackColor = false;
+ this.btnAzimuthAbsoluteEncoder.Click += new System.EventHandler(this.btnAzimuthAbsoluteEncoder_Click);
+ //
+ // AzimuthAbsoluteEncoder_lbl
+ //
+ this.AzimuthAbsoluteEncoder_lbl.AutoSize = true;
+ this.AzimuthAbsoluteEncoder_lbl.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.AzimuthAbsoluteEncoder_lbl.Location = new System.Drawing.Point(9, 36);
+ this.AzimuthAbsoluteEncoder_lbl.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
+ this.AzimuthAbsoluteEncoder_lbl.Name = "AzimuthAbsoluteEncoder_lbl";
+ this.AzimuthAbsoluteEncoder_lbl.Size = new System.Drawing.Size(155, 13);
+ this.AzimuthAbsoluteEncoder_lbl.TabIndex = 9;
+ this.AzimuthAbsoluteEncoder_lbl.Text = "Azimuth Absolute Encoder";
+ //
+ // SensorNetworkSensorInitialization
+ //
+ this.SensorNetworkSensorInitialization.BackColor = System.Drawing.Color.Gainsboro;
+ this.SensorNetworkSensorInitialization.Controls.Add(this.lblInitTimeout);
+ this.SensorNetworkSensorInitialization.Controls.Add(this.lblDataTimeout);
+ this.SensorNetworkSensorInitialization.Controls.Add(this.txtDataTimeout);
+ this.SensorNetworkSensorInitialization.Controls.Add(this.txtInitTimeout);
+ this.SensorNetworkSensorInitialization.Controls.Add(this.lblSNStatus);
+ this.SensorNetworkSensorInitialization.Controls.Add(this.UpdateSensorInitiliazation);
+ this.SensorNetworkSensorInitialization.Controls.Add(this.AzimuthEncoder);
+ this.SensorNetworkSensorInitialization.Controls.Add(this.ElevationEncoder);
+ this.SensorNetworkSensorInitialization.Controls.Add(this.CounterbalanceAccelerometer);
+ this.SensorNetworkSensorInitialization.Controls.Add(this.ElevationAccelerometer);
+ this.SensorNetworkSensorInitialization.Controls.Add(this.AzimuthAccelerometer);
+ this.SensorNetworkSensorInitialization.Controls.Add(this.AzimuthTemperature1);
+ this.SensorNetworkSensorInitialization.Controls.Add(this.ElevationTemperature1);
+ this.SensorNetworkSensorInitialization.Location = new System.Drawing.Point(344, 275);
+ this.SensorNetworkSensorInitialization.Name = "SensorNetworkSensorInitialization";
+ this.SensorNetworkSensorInitialization.Padding = new System.Windows.Forms.Padding(2);
+ this.SensorNetworkSensorInitialization.Size = new System.Drawing.Size(296, 225);
+ this.SensorNetworkSensorInitialization.TabIndex = 17;
+ this.SensorNetworkSensorInitialization.TabStop = false;
+ this.SensorNetworkSensorInitialization.Text = "Sensor Network Sensor Initialization";
+ //
+ // lblInitTimeout
+ //
+ this.lblInitTimeout.AutoSize = true;
+ this.lblInitTimeout.ForeColor = System.Drawing.Color.Black;
+ this.lblInitTimeout.Location = new System.Drawing.Point(74, 166);
+ this.lblInitTimeout.Name = "lblInitTimeout";
+ this.lblInitTimeout.Size = new System.Drawing.Size(154, 13);
+ this.lblInitTimeout.TabIndex = 78;
+ this.lblInitTimeout.Text = "Initialization Timeout (seconds):";
+ //
+ // lblDataTimeout
+ //
+ this.lblDataTimeout.AutoSize = true;
+ this.lblDataTimeout.ForeColor = System.Drawing.Color.Black;
+ this.lblDataTimeout.Location = new System.Drawing.Point(60, 146);
+ this.lblDataTimeout.Name = "lblDataTimeout";
+ this.lblDataTimeout.Size = new System.Drawing.Size(168, 13);
+ this.lblDataTimeout.TabIndex = 77;
+ this.lblDataTimeout.Text = "Data Retrieval Timeout (seconds):";
+ //
+ // txtDataTimeout
+ //
+ this.txtDataTimeout.Location = new System.Drawing.Point(242, 143);
+ this.txtDataTimeout.Name = "txtDataTimeout";
+ this.txtDataTimeout.Size = new System.Drawing.Size(44, 20);
+ this.txtDataTimeout.TabIndex = 76;
+ this.txtDataTimeout.TextChanged += new System.EventHandler(this.txtDataTimeout_TextChanged);
+ //
+ // txtInitTimeout
+ //
+ this.txtInitTimeout.Location = new System.Drawing.Point(242, 164);
+ this.txtInitTimeout.Name = "txtInitTimeout";
+ this.txtInitTimeout.Size = new System.Drawing.Size(44, 20);
+ this.txtInitTimeout.TabIndex = 75;
+ this.txtInitTimeout.TextChanged += new System.EventHandler(this.txtInitTimeout_TextChanged);
+ //
+ // lblSNStatus
+ //
+ this.lblSNStatus.AutoSize = true;
+ this.lblSNStatus.ForeColor = System.Drawing.Color.Black;
+ this.lblSNStatus.Location = new System.Drawing.Point(10, 189);
+ this.lblSNStatus.Name = "lblSNStatus";
+ this.lblSNStatus.Size = new System.Drawing.Size(40, 13);
+ this.lblSNStatus.TabIndex = 10;
+ this.lblSNStatus.Text = "Status:";
+ //
+ // UpdateSensorInitiliazation
+ //
+ this.UpdateSensorInitiliazation.Location = new System.Drawing.Point(123, 186);
+ this.UpdateSensorInitiliazation.Name = "UpdateSensorInitiliazation";
+ this.UpdateSensorInitiliazation.Size = new System.Drawing.Size(164, 23);
+ this.UpdateSensorInitiliazation.TabIndex = 9;
+ this.UpdateSensorInitiliazation.Text = "Update Sensor Configuration";
+ this.UpdateSensorInitiliazation.UseVisualStyleBackColor = true;
+ this.UpdateSensorInitiliazation.Click += new System.EventHandler(this.UpdateSensorInitiliazation_Click);
+ //
+ // AzimuthEncoder
+ //
+ this.AzimuthEncoder.AutoSize = true;
+ this.AzimuthEncoder.ForeColor = System.Drawing.Color.Red;
+ this.AzimuthEncoder.Location = new System.Drawing.Point(5, 36);
+ this.AzimuthEncoder.Name = "AzimuthEncoder";
+ this.AzimuthEncoder.Size = new System.Drawing.Size(106, 17);
+ this.AzimuthEncoder.TabIndex = 8;
+ this.AzimuthEncoder.Text = "Azimuth Encoder";
+ this.AzimuthEncoder.UseVisualStyleBackColor = true;
+ //
+ // ElevationEncoder
+ //
+ this.ElevationEncoder.AutoSize = true;
+ this.ElevationEncoder.ForeColor = System.Drawing.Color.Red;
+ this.ElevationEncoder.Location = new System.Drawing.Point(5, 18);
+ this.ElevationEncoder.Name = "ElevationEncoder";
+ this.ElevationEncoder.Size = new System.Drawing.Size(113, 17);
+ this.ElevationEncoder.TabIndex = 7;
+ this.ElevationEncoder.Text = "Elevation Encoder";
+ this.ElevationEncoder.UseVisualStyleBackColor = true;
+ //
+ // CounterbalanceAccelerometer
+ //
+ this.CounterbalanceAccelerometer.AutoSize = true;
+ this.CounterbalanceAccelerometer.Location = new System.Drawing.Point(5, 123);
+ this.CounterbalanceAccelerometer.Name = "CounterbalanceAccelerometer";
+ this.CounterbalanceAccelerometer.Size = new System.Drawing.Size(172, 17);
+ this.CounterbalanceAccelerometer.TabIndex = 6;
+ this.CounterbalanceAccelerometer.Text = "Counterbalance Accelerometer";
+ this.CounterbalanceAccelerometer.UseVisualStyleBackColor = true;
+ //
+ // ElevationAccelerometer
+ //
+ this.ElevationAccelerometer.AutoSize = true;
+ this.ElevationAccelerometer.Location = new System.Drawing.Point(5, 105);
+ this.ElevationAccelerometer.Name = "ElevationAccelerometer";
+ this.ElevationAccelerometer.Size = new System.Drawing.Size(141, 17);
+ this.ElevationAccelerometer.TabIndex = 5;
+ this.ElevationAccelerometer.Text = "Elevation Accelerometer";
+ this.ElevationAccelerometer.UseVisualStyleBackColor = true;
+ //
+ // AzimuthAccelerometer
+ //
+ this.AzimuthAccelerometer.AutoSize = true;
+ this.AzimuthAccelerometer.Location = new System.Drawing.Point(5, 87);
+ this.AzimuthAccelerometer.Name = "AzimuthAccelerometer";
+ this.AzimuthAccelerometer.Size = new System.Drawing.Size(134, 17);
+ this.AzimuthAccelerometer.TabIndex = 4;
+ this.AzimuthAccelerometer.Text = "Azimuth Accelerometer";
+ this.AzimuthAccelerometer.UseVisualStyleBackColor = true;
+ //
+ // AzimuthTemperature1
+ //
+ this.AzimuthTemperature1.AutoSize = true;
+ this.AzimuthTemperature1.Location = new System.Drawing.Point(5, 70);
+ this.AzimuthTemperature1.Name = "AzimuthTemperature1";
+ this.AzimuthTemperature1.Size = new System.Drawing.Size(156, 17);
+ this.AzimuthTemperature1.TabIndex = 2;
+ this.AzimuthTemperature1.Text = "Azimuth Motor Temperature";
+ this.AzimuthTemperature1.UseVisualStyleBackColor = true;
+ //
+ // ElevationTemperature1
+ //
+ this.ElevationTemperature1.AutoSize = true;
+ this.ElevationTemperature1.Location = new System.Drawing.Point(5, 53);
+ this.ElevationTemperature1.Name = "ElevationTemperature1";
+ this.ElevationTemperature1.Size = new System.Drawing.Size(163, 17);
+ this.ElevationTemperature1.TabIndex = 0;
+ this.ElevationTemperature1.Text = "Elevation Motor Temperature";
+ this.ElevationTemperature1.UseVisualStyleBackColor = true;
+ //
+ // SoftwareStopsThresholdGroup
+ //
+ this.SoftwareStopsThresholdGroup.BackColor = System.Drawing.Color.Gainsboro;
+ this.SoftwareStopsThresholdGroup.Controls.Add(this.SWStopLowerLabel);
+ this.SoftwareStopsThresholdGroup.Controls.Add(this.SWStopUpperLabel);
+ this.SoftwareStopsThresholdGroup.Controls.Add(this.UpdateSWStopsButton);
+ this.SoftwareStopsThresholdGroup.Controls.Add(this.LowerSWStopsLimitText);
+ this.SoftwareStopsThresholdGroup.Controls.Add(this.UpperSWStopsLimitText);
+ this.SoftwareStopsThresholdGroup.Location = new System.Drawing.Point(344, 159);
+ this.SoftwareStopsThresholdGroup.Name = "SoftwareStopsThresholdGroup";
+ this.SoftwareStopsThresholdGroup.Size = new System.Drawing.Size(296, 112);
+ this.SoftwareStopsThresholdGroup.TabIndex = 0;
+ this.SoftwareStopsThresholdGroup.TabStop = false;
+ this.SoftwareStopsThresholdGroup.Text = "Software Stops Thresholds";
+ //
+ // SWStopLowerLabel
+ //
+ this.SWStopLowerLabel.AutoSize = true;
+ this.SWStopLowerLabel.Location = new System.Drawing.Point(11, 63);
+ this.SWStopLowerLabel.Name = "SWStopLowerLabel";
+ this.SWStopLowerLabel.Size = new System.Drawing.Size(138, 13);
+ this.SWStopLowerLabel.TabIndex = 4;
+ this.SWStopLowerLabel.Text = "Software-Stops Lower Limit:";
+ //
+ // SWStopUpperLabel
+ //
+ this.SWStopUpperLabel.AutoSize = true;
+ this.SWStopUpperLabel.Location = new System.Drawing.Point(11, 22);
+ this.SWStopUpperLabel.Name = "SWStopUpperLabel";
+ this.SWStopUpperLabel.Size = new System.Drawing.Size(138, 13);
+ this.SWStopUpperLabel.TabIndex = 3;
+ this.SWStopUpperLabel.Text = "Software-Stops Upper Limit:";
+ //
+ // UpdateSWStopsButton
+ //
+ this.UpdateSWStopsButton.Location = new System.Drawing.Point(89, 86);
+ this.UpdateSWStopsButton.Name = "UpdateSWStopsButton";
+ this.UpdateSWStopsButton.Size = new System.Drawing.Size(116, 20);
+ this.UpdateSWStopsButton.TabIndex = 2;
+ this.UpdateSWStopsButton.Text = "Update Thresholds";
+ this.UpdateSWStopsButton.UseVisualStyleBackColor = true;
+ this.UpdateSWStopsButton.Click += new System.EventHandler(this.UpdateSWStopsButton_Click);
+ //
+ // LowerSWStopsLimitText
+ //
+ this.LowerSWStopsLimitText.AccessibleName = "SoftwareStopLowerLimitText";
+ this.LowerSWStopsLimitText.Location = new System.Drawing.Point(157, 63);
+ this.LowerSWStopsLimitText.Name = "LowerSWStopsLimitText";
+ this.LowerSWStopsLimitText.Size = new System.Drawing.Size(71, 20);
+ this.LowerSWStopsLimitText.TabIndex = 1;
+ this.LowerSWStopsLimitText.TextChanged += new System.EventHandler(this.LowerSWStopsLimitText_TextChanged);
+ //
+ // UpperSWStopsLimitText
+ //
+ this.UpperSWStopsLimitText.AccessibleName = "SoftwareStopUpperLimitText";
+ this.UpperSWStopsLimitText.Location = new System.Drawing.Point(157, 22);
+ this.UpperSWStopsLimitText.Name = "UpperSWStopsLimitText";
+ this.UpperSWStopsLimitText.Size = new System.Drawing.Size(71, 20);
+ this.UpperSWStopsLimitText.TabIndex = 0;
+ this.UpperSWStopsLimitText.TextChanged += new System.EventHandler(this.UpperSWStopsLimitText_TextChanged);
+ //
+ // grpProximitySensors
+ //
+ this.grpProximitySensors.BackColor = System.Drawing.Color.Gainsboro;
+ this.grpProximitySensors.Controls.Add(this.label4);
+ this.grpProximitySensors.Controls.Add(this.label21);
+ this.grpProximitySensors.Controls.Add(this.ElivationLimitSwitch0);
+ this.grpProximitySensors.Controls.Add(this.ElevationLimitSwitch90);
+ this.grpProximitySensors.Location = new System.Drawing.Point(3, 275);
+ this.grpProximitySensors.Name = "grpProximitySensors";
+ this.grpProximitySensors.Padding = new System.Windows.Forms.Padding(2);
+ this.grpProximitySensors.Size = new System.Drawing.Size(338, 101);
+ this.grpProximitySensors.TabIndex = 15;
+ this.grpProximitySensors.TabStop = false;
+ this.grpProximitySensors.Text = " Proximity Sensors";
+ //
+ // label4
+ //
+ this.label4.AutoSize = true;
+ this.label4.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.label4.Location = new System.Drawing.Point(9, 63);
+ this.label4.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
+ this.label4.Name = "label4";
+ this.label4.Size = new System.Drawing.Size(155, 13);
+ this.label4.TabIndex = 10;
+ this.label4.Text = "Elevation Limit Switch 90°";
//
// label21
//
this.label21.AutoSize = true;
- this.label21.Location = new System.Drawing.Point(245, 534);
+ this.label21.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.label21.Location = new System.Drawing.Point(9, 30);
+ this.label21.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.label21.Name = "label21";
- this.label21.Size = new System.Drawing.Size(95, 13);
- this.label21.TabIndex = 71;
- this.label21.Text = "Has Active Move?";
+ this.label21.Size = new System.Drawing.Size(148, 13);
+ this.label21.TabIndex = 9;
+ this.label21.Text = "Elevation Limit Switch 0°";
+ //
+ // ElivationLimitSwitch0
+ //
+ this.ElivationLimitSwitch0.BackColor = System.Drawing.Color.Yellow;
+ this.ElivationLimitSwitch0.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+ this.ElivationLimitSwitch0.Location = new System.Drawing.Point(228, 25);
+ this.ElivationLimitSwitch0.Name = "ElivationLimitSwitch0";
+ this.ElivationLimitSwitch0.Size = new System.Drawing.Size(89, 23);
+ this.ElivationLimitSwitch0.TabIndex = 13;
+ this.ElivationLimitSwitch0.Text = "NOT LOADED";
+ this.ElivationLimitSwitch0.UseVisualStyleBackColor = false;
+ this.ElivationLimitSwitch0.Click += new System.EventHandler(this.ElevationProximityOverideButton1_Click);
+ //
+ // ElevationLimitSwitch90
+ //
+ this.ElevationLimitSwitch90.BackColor = System.Drawing.Color.Yellow;
+ this.ElevationLimitSwitch90.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+ this.ElevationLimitSwitch90.Location = new System.Drawing.Point(228, 58);
+ this.ElevationLimitSwitch90.Name = "ElevationLimitSwitch90";
+ this.ElevationLimitSwitch90.Size = new System.Drawing.Size(89, 23);
+ this.ElevationLimitSwitch90.TabIndex = 14;
+ this.ElevationLimitSwitch90.Text = "NOT LOADED";
+ this.ElevationLimitSwitch90.UseVisualStyleBackColor = false;
+ this.ElevationLimitSwitch90.Click += new System.EventHandler(this.ElevationProximityOverideButton2_Click);
+ //
+ // MotorTemperatureSensors
+ //
+ this.MotorTemperatureSensors.BackColor = System.Drawing.Color.Gainsboro;
+ this.MotorTemperatureSensors.Controls.Add(this.ElMotTempSensOverride);
+ this.MotorTemperatureSensors.Controls.Add(this.label29);
+ this.MotorTemperatureSensors.Controls.Add(this.AzMotTempSensOverride);
+ this.MotorTemperatureSensors.Controls.Add(this.label28);
+ this.MotorTemperatureSensors.Location = new System.Drawing.Point(3, 159);
+ this.MotorTemperatureSensors.Name = "MotorTemperatureSensors";
+ this.MotorTemperatureSensors.Size = new System.Drawing.Size(338, 112);
+ this.MotorTemperatureSensors.TabIndex = 29;
+ this.MotorTemperatureSensors.TabStop = false;
+ this.MotorTemperatureSensors.Text = "Motor Temperature Sensors";
+ //
+ // ElMotTempSensOverride
+ //
+ this.ElMotTempSensOverride.BackColor = System.Drawing.Color.Yellow;
+ this.ElMotTempSensOverride.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+ this.ElMotTempSensOverride.Location = new System.Drawing.Point(228, 63);
+ this.ElMotTempSensOverride.Margin = new System.Windows.Forms.Padding(2);
+ this.ElMotTempSensOverride.Name = "ElMotTempSensOverride";
+ this.ElMotTempSensOverride.Size = new System.Drawing.Size(89, 23);
+ this.ElMotTempSensOverride.TabIndex = 15;
+ this.ElMotTempSensOverride.Text = "NOT LOADED";
+ this.ElMotTempSensOverride.UseVisualStyleBackColor = false;
+ this.ElMotTempSensOverride.Click += new System.EventHandler(this.ElMotTempSensOverride_Click);
+ //
+ // label29
+ //
+ this.label29.AutoSize = true;
+ this.label29.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.label29.Location = new System.Drawing.Point(9, 68);
+ this.label29.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
+ this.label29.Name = "label29";
+ this.label29.Size = new System.Drawing.Size(214, 13);
+ this.label29.TabIndex = 14;
+ this.label29.Text = "Elevation Motor Temperature Sensor";
+ //
+ // AzMotTempSensOverride
+ //
+ this.AzMotTempSensOverride.BackColor = System.Drawing.Color.Yellow;
+ this.AzMotTempSensOverride.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+ this.AzMotTempSensOverride.Location = new System.Drawing.Point(228, 30);
+ this.AzMotTempSensOverride.Margin = new System.Windows.Forms.Padding(2);
+ this.AzMotTempSensOverride.Name = "AzMotTempSensOverride";
+ this.AzMotTempSensOverride.Size = new System.Drawing.Size(89, 23);
+ this.AzMotTempSensOverride.TabIndex = 13;
+ this.AzMotTempSensOverride.Text = "NOT LOADED";
+ this.AzMotTempSensOverride.UseVisualStyleBackColor = false;
+ this.AzMotTempSensOverride.Click += new System.EventHandler(this.AzMotTempSensOverride_Click);
+ //
+ // label28
+ //
+ this.label28.AutoSize = true;
+ this.label28.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.label28.Location = new System.Drawing.Point(9, 35);
+ this.label28.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
+ this.label28.Name = "label28";
+ this.label28.Size = new System.Drawing.Size(205, 13);
+ this.label28.TabIndex = 12;
+ this.label28.Text = "Azimuth Motor Temperature Sensor";
+ //
+ // GatesSensors
+ //
+ this.GatesSensors.BackColor = System.Drawing.Color.Gainsboro;
+ this.GatesSensors.Controls.Add(this.MGOverride);
+ this.GatesSensors.Controls.Add(this.label27);
+ this.GatesSensors.Location = new System.Drawing.Point(3, 86);
+ this.GatesSensors.Name = "GatesSensors";
+ this.GatesSensors.Size = new System.Drawing.Size(338, 69);
+ this.GatesSensors.TabIndex = 28;
+ this.GatesSensors.TabStop = false;
+ this.GatesSensors.Text = "Gates Sensors";
+ //
+ // MGOverride
+ //
+ this.MGOverride.BackColor = System.Drawing.Color.Yellow;
+ this.MGOverride.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+ this.MGOverride.Location = new System.Drawing.Point(228, 26);
+ this.MGOverride.Margin = new System.Windows.Forms.Padding(2);
+ this.MGOverride.Name = "MGOverride";
+ this.MGOverride.Size = new System.Drawing.Size(89, 23);
+ this.MGOverride.TabIndex = 13;
+ this.MGOverride.Text = "NOT LOADED";
+ this.MGOverride.UseVisualStyleBackColor = false;
+ this.MGOverride.Click += new System.EventHandler(this.MGOverride_Click);
+ //
+ // label27
+ //
+ this.label27.AutoSize = true;
+ this.label27.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.label27.Location = new System.Drawing.Point(9, 31);
+ this.label27.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
+ this.label27.Name = "label27";
+ this.label27.Size = new System.Drawing.Size(120, 13);
+ this.label27.TabIndex = 12;
+ this.label27.Text = "Main Gates Sensors";
+ //
+ // Accelerometers
+ //
+ this.Accelerometers.BackColor = System.Drawing.Color.Gainsboro;
+ this.Accelerometers.Controls.Add(this.btnElevationMotorAccelerometerOverride);
+ this.Accelerometers.Controls.Add(this.btnCounterbalanceMotorAccelerometerOverride);
+ this.Accelerometers.Controls.Add(this.btnAzimuthMotorAccelerometerOverride);
+ this.Accelerometers.Controls.Add(this.label33);
+ this.Accelerometers.Controls.Add(this.label3);
+ this.Accelerometers.Controls.Add(this.label22);
+ this.Accelerometers.Location = new System.Drawing.Point(344, 3);
+ this.Accelerometers.Name = "Accelerometers";
+ this.Accelerometers.Padding = new System.Windows.Forms.Padding(2);
+ this.Accelerometers.Size = new System.Drawing.Size(296, 152);
+ this.Accelerometers.TabIndex = 0;
+ this.Accelerometers.TabStop = false;
+ this.Accelerometers.Text = "Accelerometers";
+ //
+ // btnElevationMotorAccelerometerOverride
+ //
+ this.btnElevationMotorAccelerometerOverride.BackColor = System.Drawing.Color.Yellow;
+ this.btnElevationMotorAccelerometerOverride.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+ this.btnElevationMotorAccelerometerOverride.Location = new System.Drawing.Point(194, 71);
+ this.btnElevationMotorAccelerometerOverride.Name = "btnElevationMotorAccelerometerOverride";
+ this.btnElevationMotorAccelerometerOverride.Size = new System.Drawing.Size(89, 23);
+ this.btnElevationMotorAccelerometerOverride.TabIndex = 14;
+ this.btnElevationMotorAccelerometerOverride.Text = "NOT LOADED";
+ this.btnElevationMotorAccelerometerOverride.UseVisualStyleBackColor = false;
+ this.btnElevationMotorAccelerometerOverride.Click += new System.EventHandler(this.btnElevationMotorAccelerometerOverride_Click);
+ //
+ // btnCounterbalanceMotorAccelerometerOverride
+ //
+ this.btnCounterbalanceMotorAccelerometerOverride.BackColor = System.Drawing.Color.Yellow;
+ this.btnCounterbalanceMotorAccelerometerOverride.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+ this.btnCounterbalanceMotorAccelerometerOverride.Location = new System.Drawing.Point(194, 120);
+ this.btnCounterbalanceMotorAccelerometerOverride.Name = "btnCounterbalanceMotorAccelerometerOverride";
+ this.btnCounterbalanceMotorAccelerometerOverride.Size = new System.Drawing.Size(89, 23);
+ this.btnCounterbalanceMotorAccelerometerOverride.TabIndex = 16;
+ this.btnCounterbalanceMotorAccelerometerOverride.Text = "NOT LOADED";
+ this.btnCounterbalanceMotorAccelerometerOverride.UseVisualStyleBackColor = false;
+ this.btnCounterbalanceMotorAccelerometerOverride.Click += new System.EventHandler(this.btnCounterbalanceMotorAccelerometerOverride_Click);
+ //
+ // btnAzimuthMotorAccelerometerOverride
+ //
+ this.btnAzimuthMotorAccelerometerOverride.BackColor = System.Drawing.Color.Yellow;
+ this.btnAzimuthMotorAccelerometerOverride.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+ this.btnAzimuthMotorAccelerometerOverride.Location = new System.Drawing.Point(194, 22);
+ this.btnAzimuthMotorAccelerometerOverride.Name = "btnAzimuthMotorAccelerometerOverride";
+ this.btnAzimuthMotorAccelerometerOverride.Size = new System.Drawing.Size(89, 23);
+ this.btnAzimuthMotorAccelerometerOverride.TabIndex = 13;
+ this.btnAzimuthMotorAccelerometerOverride.Text = "NOT LOADED";
+ this.btnAzimuthMotorAccelerometerOverride.UseVisualStyleBackColor = false;
+ this.btnAzimuthMotorAccelerometerOverride.Click += new System.EventHandler(this.btnAzimuthMotorAccelerometerOverride_Click);
+ //
+ // label33
+ //
+ this.label33.AutoSize = true;
+ this.label33.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.label33.Location = new System.Drawing.Point(5, 125);
+ this.label33.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
+ this.label33.Name = "label33";
+ this.label33.Size = new System.Drawing.Size(181, 13);
+ this.label33.TabIndex = 15;
+ this.label33.Text = "Counterbalance Accelerometer";
+ //
+ // label3
+ //
+ this.label3.AutoSize = true;
+ this.label3.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.label3.Location = new System.Drawing.Point(5, 76);
+ this.label3.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
+ this.label3.Name = "label3";
+ this.label3.Size = new System.Drawing.Size(181, 13);
+ this.label3.TabIndex = 10;
+ this.label3.Text = "Elevation Motor Accelerometer";
//
// label22
//
this.label22.AutoSize = true;
- this.label22.Location = new System.Drawing.Point(346, 534);
+ this.label22.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.label22.Location = new System.Drawing.Point(5, 27);
+ this.label22.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.label22.Name = "label22";
- this.label22.Size = new System.Drawing.Size(29, 13);
- this.label22.TabIndex = 72;
- this.label22.Text = "True";
+ this.label22.Size = new System.Drawing.Size(172, 13);
+ this.label22.TabIndex = 9;
+ this.label22.Text = "Azimuth Motor Accelerometer";
+ //
+ // WeatherStation
+ //
+ this.WeatherStation.BackColor = System.Drawing.Color.Gainsboro;
+ this.WeatherStation.Controls.Add(this.WSOverride);
+ this.WeatherStation.Controls.Add(this.label24);
+ this.WeatherStation.Location = new System.Drawing.Point(2, 3);
+ this.WeatherStation.Margin = new System.Windows.Forms.Padding(2);
+ this.WeatherStation.Name = "WeatherStation";
+ this.WeatherStation.Padding = new System.Windows.Forms.Padding(2);
+ this.WeatherStation.Size = new System.Drawing.Size(339, 79);
+ this.WeatherStation.TabIndex = 27;
+ this.WeatherStation.TabStop = false;
+ this.WeatherStation.Text = "Weather Station";
+ //
+ // WSOverride
+ //
+ this.WSOverride.BackColor = System.Drawing.Color.Yellow;
+ this.WSOverride.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+ this.WSOverride.Location = new System.Drawing.Point(228, 30);
+ this.WSOverride.Margin = new System.Windows.Forms.Padding(2);
+ this.WSOverride.Name = "WSOverride";
+ this.WSOverride.Size = new System.Drawing.Size(89, 23);
+ this.WSOverride.TabIndex = 13;
+ this.WSOverride.Text = "NOT LOADED";
+ this.WSOverride.UseVisualStyleBackColor = false;
+ this.WSOverride.Click += new System.EventHandler(this.WSOverride_Click);
+ //
+ // label24
+ //
+ this.label24.AutoSize = true;
+ this.label24.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.label24.Location = new System.Drawing.Point(9, 35);
+ this.label24.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
+ this.label24.Name = "label24";
+ this.label24.Size = new System.Drawing.Size(99, 13);
+ this.label24.TabIndex = 12;
+ this.label24.Text = "Weather Station";
+ //
+ // tabPage4
+ //
+ this.tabPage4.Controls.Add(this.lblModeType);
+ this.tabPage4.Controls.Add(this.spectraModeTypeVal);
+ this.tabPage4.Controls.Add(this.lblFrequency);
+ this.tabPage4.Controls.Add(this.frequencyVal);
+ this.tabPage4.Controls.Add(this.spectraCyberScanChart);
+ this.tabPage4.Controls.Add(this.lblIntegrationStep);
+ this.tabPage4.Controls.Add(this.IntegrationStepVal);
+ this.tabPage4.Controls.Add(this.lblDCGain);
+ this.tabPage4.Controls.Add(this.DCGainVal);
+ this.tabPage4.Controls.Add(this.lblIFGain);
+ this.tabPage4.Controls.Add(this.IFGainVal);
+ this.tabPage4.Controls.Add(this.lblBandwidth);
+ this.tabPage4.Controls.Add(this.BandwidthVal);
+ this.tabPage4.Controls.Add(this.lblOffsetVoltage);
+ this.tabPage4.Controls.Add(this.OffsetVoltageVal);
+ this.tabPage4.Location = new System.Drawing.Point(4, 22);
+ this.tabPage4.Name = "tabPage4";
+ this.tabPage4.Padding = new System.Windows.Forms.Padding(3);
+ this.tabPage4.Size = new System.Drawing.Size(645, 505);
+ this.tabPage4.TabIndex = 3;
+ this.tabPage4.Text = "RFData";
+ this.tabPage4.UseVisualStyleBackColor = true;
+ //
+ // lblModeType
+ //
+ this.lblModeType.AutoSize = true;
+ this.lblModeType.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.lblModeType.Location = new System.Drawing.Point(155, 333);
+ this.lblModeType.Name = "lblModeType";
+ this.lblModeType.Size = new System.Drawing.Size(128, 15);
+ this.lblModeType.TabIndex = 19;
+ this.lblModeType.Text = "SpectraCyberMode";
+ //
+ // spectraModeTypeVal
+ //
+ this.spectraModeTypeVal.AutoSize = true;
+ this.spectraModeTypeVal.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.spectraModeTypeVal.Location = new System.Drawing.Point(369, 333);
+ this.spectraModeTypeVal.Name = "spectraModeTypeVal";
+ this.spectraModeTypeVal.Size = new System.Drawing.Size(35, 15);
+ this.spectraModeTypeVal.TabIndex = 20;
+ this.spectraModeTypeVal.Text = "NaN";
+ //
+ // lblFrequency
+ //
+ this.lblFrequency.AutoSize = true;
+ this.lblFrequency.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.lblFrequency.Location = new System.Drawing.Point(300, 369);
+ this.lblFrequency.Name = "lblFrequency";
+ this.lblFrequency.Size = new System.Drawing.Size(73, 15);
+ this.lblFrequency.TabIndex = 17;
+ this.lblFrequency.Text = "Frequency";
+ //
+ // frequencyVal
+ //
+ this.frequencyVal.AutoSize = true;
+ this.frequencyVal.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.frequencyVal.Location = new System.Drawing.Point(514, 369);
+ this.frequencyVal.Name = "frequencyVal";
+ this.frequencyVal.Size = new System.Drawing.Size(35, 15);
+ this.frequencyVal.TabIndex = 18;
+ this.frequencyVal.Text = "NaN";
+ //
+ // spectraCyberScanChart
+ //
+ chartArea4.AxisX.Title = "Time";
+ chartArea4.AxisY.Title = "RF Data";
+ chartArea4.Name = "ChartArea1";
+ this.spectraCyberScanChart.ChartAreas.Add(chartArea4);
+ legend1.Name = "Legend1";
+ this.spectraCyberScanChart.Legends.Add(legend1);
+ this.spectraCyberScanChart.Location = new System.Drawing.Point(36, 0);
+ this.spectraCyberScanChart.Name = "spectraCyberScanChart";
+ series13.ChartArea = "ChartArea1";
+ series13.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Spline;
+ series13.Legend = "Legend1";
+ series13.Name = "Data/Time";
+ this.spectraCyberScanChart.Series.Add(series13);
+ this.spectraCyberScanChart.Size = new System.Drawing.Size(571, 279);
+ this.spectraCyberScanChart.TabIndex = 16;
+ this.spectraCyberScanChart.Text = "spectraCyberScanChart";
+ //
+ // lblIntegrationStep
+ //
+ this.lblIntegrationStep.AutoSize = true;
+ this.lblIntegrationStep.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.lblIntegrationStep.Location = new System.Drawing.Point(300, 399);
+ this.lblIntegrationStep.Name = "lblIntegrationStep";
+ this.lblIntegrationStep.Size = new System.Drawing.Size(105, 15);
+ this.lblIntegrationStep.TabIndex = 14;
+ this.lblIntegrationStep.Text = "IntegrationStep";
+ //
+ // IntegrationStepVal
+ //
+ this.IntegrationStepVal.AutoSize = true;
+ this.IntegrationStepVal.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.IntegrationStepVal.Location = new System.Drawing.Point(514, 399);
+ this.IntegrationStepVal.Name = "IntegrationStepVal";
+ this.IntegrationStepVal.Size = new System.Drawing.Size(35, 15);
+ this.IntegrationStepVal.TabIndex = 15;
+ this.IntegrationStepVal.Text = "NaN";
+ //
+ // lblDCGain
+ //
+ this.lblDCGain.AutoSize = true;
+ this.lblDCGain.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.lblDCGain.Location = new System.Drawing.Point(6, 425);
+ this.lblDCGain.Name = "lblDCGain";
+ this.lblDCGain.Size = new System.Drawing.Size(56, 15);
+ this.lblDCGain.TabIndex = 12;
+ this.lblDCGain.Text = "DCGain";
+ //
+ // DCGainVal
+ //
+ this.DCGainVal.AutoSize = true;
+ this.DCGainVal.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.DCGainVal.Location = new System.Drawing.Point(220, 425);
+ this.DCGainVal.Name = "DCGainVal";
+ this.DCGainVal.Size = new System.Drawing.Size(35, 15);
+ this.DCGainVal.TabIndex = 13;
+ this.DCGainVal.Text = "NaN";
+ //
+ // lblIFGain
+ //
+ this.lblIFGain.AutoSize = true;
+ this.lblIFGain.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.lblIFGain.Location = new System.Drawing.Point(6, 399);
+ this.lblIFGain.Name = "lblIFGain";
+ this.lblIFGain.Size = new System.Drawing.Size(53, 15);
+ this.lblIFGain.TabIndex = 10;
+ this.lblIFGain.Text = "IF Gain";
+ //
+ // IFGainVal
+ //
+ this.IFGainVal.AutoSize = true;
+ this.IFGainVal.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.IFGainVal.Location = new System.Drawing.Point(220, 399);
+ this.IFGainVal.Name = "IFGainVal";
+ this.IFGainVal.Size = new System.Drawing.Size(35, 15);
+ this.IFGainVal.TabIndex = 11;
+ this.IFGainVal.Text = "NaN";
+ //
+ // lblBandwidth
+ //
+ this.lblBandwidth.AutoSize = true;
+ this.lblBandwidth.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.lblBandwidth.Location = new System.Drawing.Point(6, 369);
+ this.lblBandwidth.Name = "lblBandwidth";
+ this.lblBandwidth.Size = new System.Drawing.Size(74, 15);
+ this.lblBandwidth.TabIndex = 8;
+ this.lblBandwidth.Text = "Bandwidth";
+ //
+ // BandwidthVal
+ //
+ this.BandwidthVal.AutoSize = true;
+ this.BandwidthVal.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.BandwidthVal.Location = new System.Drawing.Point(220, 369);
+ this.BandwidthVal.Name = "BandwidthVal";
+ this.BandwidthVal.Size = new System.Drawing.Size(35, 15);
+ this.BandwidthVal.TabIndex = 9;
+ this.BandwidthVal.Text = "NaN";
+ //
+ // lblOffsetVoltage
+ //
+ this.lblOffsetVoltage.AutoSize = true;
+ this.lblOffsetVoltage.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.lblOffsetVoltage.Location = new System.Drawing.Point(300, 425);
+ this.lblOffsetVoltage.Name = "lblOffsetVoltage";
+ this.lblOffsetVoltage.Size = new System.Drawing.Size(92, 15);
+ this.lblOffsetVoltage.TabIndex = 6;
+ this.lblOffsetVoltage.Text = "OffsetVoltage";
+ //
+ // OffsetVoltageVal
+ //
+ this.OffsetVoltageVal.AutoSize = true;
+ this.OffsetVoltageVal.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.OffsetVoltageVal.Location = new System.Drawing.Point(514, 425);
+ this.OffsetVoltageVal.Name = "OffsetVoltageVal";
+ this.OffsetVoltageVal.Size = new System.Drawing.Size(35, 15);
+ this.OffsetVoltageVal.TabIndex = 7;
+ this.OffsetVoltageVal.Text = "NaN";
+ //
+ // tabPage5
+ //
+ this.tabPage5.Controls.Add(this.consoleLogBox);
+ this.tabPage5.Location = new System.Drawing.Point(4, 22);
+ this.tabPage5.Name = "tabPage5";
+ this.tabPage5.Padding = new System.Windows.Forms.Padding(3);
+ this.tabPage5.Size = new System.Drawing.Size(645, 505);
+ this.tabPage5.TabIndex = 4;
+ this.tabPage5.Text = "Console Log";
+ this.tabPage5.UseVisualStyleBackColor = true;
+ //
+ // consoleLogBox
+ //
+ this.consoleLogBox.AcceptsReturn = true;
+ this.consoleLogBox.AcceptsTab = true;
+ this.consoleLogBox.AllowDrop = true;
+ this.consoleLogBox.Location = new System.Drawing.Point(6, 6);
+ this.consoleLogBox.Multiline = true;
+ this.consoleLogBox.Name = "consoleLogBox";
+ this.consoleLogBox.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
+ this.consoleLogBox.Size = new System.Drawing.Size(631, 494);
+ this.consoleLogBox.TabIndex = 0;
//
// DiagnosticsForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
- this.ClientSize = new System.Drawing.Size(1419, 682);
- this.Controls.Add(this.label22);
- this.Controls.Add(this.label21);
- this.Controls.Add(this.label19);
- this.Controls.Add(this.label18);
- this.Controls.Add(this.textBox4);
- this.Controls.Add(this.textBox3);
+ this.ClientSize = new System.Drawing.Size(655, 547);
+ this.Controls.Add(this.tabControl1);
this.Controls.Add(this.label15);
- this.Controls.Add(this.label13);
- this.Controls.Add(this.textBox2);
- this.Controls.Add(this.label12);
- this.Controls.Add(this.lblElEncoderTicks);
- this.Controls.Add(this.label14);
- this.Controls.Add(this.lblElEncoderDegrees);
- this.Controls.Add(this.label16);
- this.Controls.Add(this.label17);
- this.Controls.Add(this.textBox1);
- this.Controls.Add(this.label10);
- this.Controls.Add(this.button1);
- this.Controls.Add(this.button2);
- this.Controls.Add(this.button3);
- this.Controls.Add(this.button4);
- this.Controls.Add(this.button5);
- this.Controls.Add(this.button6);
- this.Controls.Add(this.txtCustEncoderVal);
- this.Controls.Add(this.label9);
- this.Controls.Add(this.btnSubtractXEncoder);
- this.Controls.Add(this.btnSubtractFiveEncoder);
- this.Controls.Add(this.btnSubtractOneEncoder);
- this.Controls.Add(this.btnAddXEncoder);
- this.Controls.Add(this.btnAddFiveEncoder);
- this.Controls.Add(this.btnAddOneEncoder);
- this.Controls.Add(this.lblAzEncoderTicks);
- this.Controls.Add(this.lblEncoderTicks);
- this.Controls.Add(this.lblAzEncoderDegrees);
- this.Controls.Add(this.lblEncoderDegrees);
- this.Controls.Add(this.lblAbsEncoder);
- this.Controls.Add(this.panel1);
- this.Controls.Add(this.label11);
- this.Controls.Add(this.txtCustTemp);
- this.Controls.Add(this.btnSubtractXTemp);
- this.Controls.Add(this.btnSubtractFiveTemp);
- this.Controls.Add(this.btnSubtractOneTemp);
- this.Controls.Add(this.selectDemo);
- this.Controls.Add(this.lblShutdown);
- this.Controls.Add(this.btnAddXTemp);
- this.Controls.Add(this.btnAddFiveTemp);
- this.Controls.Add(this.btnAddOneTemp);
- this.Controls.Add(this.fanLabel);
- this.Controls.Add(this.warningLabel);
- this.Controls.Add(this.btnTest);
- this.Controls.Add(this.txtTemperature);
- this.Controls.Add(this.fldElTemp);
- this.Controls.Add(this.fldAzTemp);
- this.Controls.Add(this.radioButton2);
- this.Controls.Add(this.radioButton1);
- this.Controls.Add(this.lblElevationTemp);
- this.Controls.Add(this.lblAzimuthTemp);
- this.Controls.Add(this.label8);
- this.Controls.Add(this.statusTextBox);
- this.Controls.Add(this.endTimeTextBox);
- this.Controls.Add(this.startTimeTextBox);
- this.Controls.Add(this.label7);
- this.Controls.Add(this.label6);
- this.Controls.Add(this.label5);
- this.Controls.Add(this.label4);
- this.Controls.Add(this.label3);
- this.Controls.Add(this.lblCurrentElOrientation);
- this.Controls.Add(this.lblCurrentAzOrientation);
- this.Controls.Add(this.dataGridView1);
+ this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.Margin = new System.Windows.Forms.Padding(2);
- this.MinimumSize = new System.Drawing.Size(615, 249);
+ this.MinimumSize = new System.Drawing.Size(352, 175);
this.Name = "DiagnosticsForm";
this.Text = "DiagnosticsForm";
this.Load += new System.EventHandler(this.DiagnosticsForm_Load);
((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit();
- this.panel1.ResumeLayout(false);
- this.panel1.PerformLayout();
+ this.tabControl1.ResumeLayout(false);
+ this.tabPage1.ResumeLayout(false);
+ this.groupBox9.ResumeLayout(false);
+ this.groupBox9.PerformLayout();
+ this.groupBox8.ResumeLayout(false);
+ this.groupBox3.ResumeLayout(false);
+ this.groupBox3.PerformLayout();
+ this.groupBox2.ResumeLayout(false);
+ this.splitContainer2.Panel1.ResumeLayout(false);
+ this.splitContainer2.Panel1.PerformLayout();
+ this.splitContainer2.Panel2.ResumeLayout(false);
+ this.splitContainer2.Panel2.PerformLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.splitContainer2)).EndInit();
+ this.splitContainer2.ResumeLayout(false);
+ this.groupBox1.ResumeLayout(false);
+ this.groupBox1.PerformLayout();
+ this.tabPage2.ResumeLayout(false);
+ this.grpAccelerometerSensorData.ResumeLayout(false);
+ this.grpAccelerometerSensorData.PerformLayout();
+ this.pnlCounterbalanceAccelerometer.ResumeLayout(false);
+ this.pnlCounterbalanceAccelerometer.PerformLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.counterBalanceAccChart)).EndInit();
+ this.pnlElevationMotorAccelerometer.ResumeLayout(false);
+ this.pnlElevationMotorAccelerometer.PerformLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.elevationAccChart)).EndInit();
+ this.pnlAzimuthMotorAccelerometer.ResumeLayout(false);
+ this.pnlAzimuthMotorAccelerometer.PerformLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.azimuthAccChart)).EndInit();
+ this.grpSensorData.ResumeLayout(false);
+ this.grpSensorData.PerformLayout();
+ this.grpMcuStatus.ResumeLayout(false);
+ this.grpMcuStatus.PerformLayout();
+ this.groupBox14.ResumeLayout(false);
+ this.grpAbsoluteMotorPositionsTemperatures.ResumeLayout(false);
+ this.splitContainer1.Panel1.ResumeLayout(false);
+ this.splitContainer1.Panel1.PerformLayout();
+ this.splitContainer1.Panel2.ResumeLayout(false);
+ this.splitContainer1.Panel2.PerformLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit();
+ this.splitContainer1.ResumeLayout(false);
+ this.groupBox5.ResumeLayout(false);
+ this.groupBox5.PerformLayout();
+ this.tabPage3.ResumeLayout(false);
+ this.Encoders.ResumeLayout(false);
+ this.Encoders.PerformLayout();
+ this.SensorNetworkSensorInitialization.ResumeLayout(false);
+ this.SensorNetworkSensorInitialization.PerformLayout();
+ this.SoftwareStopsThresholdGroup.ResumeLayout(false);
+ this.SoftwareStopsThresholdGroup.PerformLayout();
+ this.grpProximitySensors.ResumeLayout(false);
+ this.grpProximitySensors.PerformLayout();
+ this.MotorTemperatureSensors.ResumeLayout(false);
+ this.MotorTemperatureSensors.PerformLayout();
+ this.GatesSensors.ResumeLayout(false);
+ this.GatesSensors.PerformLayout();
+ this.Accelerometers.ResumeLayout(false);
+ this.Accelerometers.PerformLayout();
+ this.WeatherStation.ResumeLayout(false);
+ this.WeatherStation.PerformLayout();
+ this.tabPage4.ResumeLayout(false);
+ this.tabPage4.PerformLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.spectraCyberScanChart)).EndInit();
+ this.tabPage5.ResumeLayout(false);
+ this.tabPage5.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
@@ -1080,11 +2749,8 @@ private void InitializeComponent()
#endregion
private System.Windows.Forms.DataGridView dataGridView1;
- private System.Windows.Forms.Label lblCurrentAzOrientation;
- private System.Windows.Forms.Label lblCurrentElOrientation;
- private System.Windows.Forms.Label label3;
- private System.Windows.Forms.Label label4;
- private System.Windows.Forms.Label label5;
+ private System.Windows.Forms.Label windSpeedLabel;
+ private System.Windows.Forms.Label windDirLabel;
private System.Windows.Forms.Label label6;
private System.Windows.Forms.Label label7;
private System.Windows.Forms.TextBox startTimeTextBox;
@@ -1094,43 +2760,10 @@ private void InitializeComponent()
private System.Windows.Forms.Timer timer1;
private System.Windows.Forms.Label lblAzimuthTemp;
private System.Windows.Forms.Label lblElevationTemp;
- private System.Windows.Forms.RadioButton radioButton1;
- private System.Windows.Forms.RadioButton radioButton2;
private System.Windows.Forms.Label fldAzTemp;
private System.Windows.Forms.Label fldElTemp;
- private System.Windows.Forms.TextBox txtTemperature;
private System.Windows.Forms.Button btnTest;
- private System.Windows.Forms.Label warningLabel;
- private System.Windows.Forms.Label fanLabel;
- private System.Windows.Forms.Button btnAddOneTemp;
- private System.Windows.Forms.Button btnAddFiveTemp;
- private System.Windows.Forms.Button btnAddXTemp;
- private System.Windows.Forms.Label lblShutdown;
private System.Windows.Forms.CheckBox selectDemo;
- private System.Windows.Forms.Button btnSubtractOneTemp;
- private System.Windows.Forms.Button btnSubtractFiveTemp;
- private System.Windows.Forms.Button btnSubtractXTemp;
- private System.Windows.Forms.TextBox txtCustTemp;
- private System.Windows.Forms.Label label11;
- private System.Windows.Forms.Panel panel1;
- private System.Windows.Forms.Label lblElLimStatus2;
- private System.Windows.Forms.Label lblElLimStatus1;
- private System.Windows.Forms.Label lblAzLimStatus2;
- private System.Windows.Forms.Label lblAzLimStatus1;
- private System.Windows.Forms.Label lblElLimit2;
- private System.Windows.Forms.Label lblElLimit1;
- private System.Windows.Forms.Label lblAzLimit2;
- private System.Windows.Forms.Label lblAzLimit1;
- private System.Windows.Forms.Label lblEleProx2;
- private System.Windows.Forms.Label lblEleProx1;
- private System.Windows.Forms.Label lblElProx2;
- private System.Windows.Forms.Label lblElProx1;
- private System.Windows.Forms.Label lblAzProxStatus3;
- private System.Windows.Forms.Label lblAzProxStatus2;
- private System.Windows.Forms.Label lblAzProxStatus1;
- private System.Windows.Forms.Label lblAzProx3;
- private System.Windows.Forms.Label lblAzProx2;
- private System.Windows.Forms.Label lblAzProx1;
private System.Windows.Forms.Label lblAbsEncoder;
private System.Windows.Forms.Label lblEncoderDegrees;
private System.Windows.Forms.Label lblAzEncoderDegrees;
@@ -1164,8 +2797,160 @@ private void InitializeComponent()
private System.Windows.Forms.TextBox textBox3;
private System.Windows.Forms.TextBox textBox4;
private System.Windows.Forms.Label label18;
+ private System.Windows.Forms.TabControl tabControl1;
+ private System.Windows.Forms.TabPage tabPage1;
+ private System.Windows.Forms.TabPage tabPage2;
+ private System.Windows.Forms.GroupBox groupBox1;
+ private System.Windows.Forms.GroupBox groupBox2;
+ private System.Windows.Forms.GroupBox groupBox3;
+ private System.Windows.Forms.GroupBox grpAbsoluteMotorPositionsTemperatures;
+ private System.Windows.Forms.GroupBox groupBox5;
private System.Windows.Forms.Label label19;
- private System.Windows.Forms.Label label21;
+ private System.Windows.Forms.Label label20;
+ private System.Windows.Forms.Label label1;
+ private System.Windows.Forms.Label label2;
+ private System.Windows.Forms.Label label5;
+ private System.Windows.Forms.Label label11;
+ private System.Windows.Forms.Label barometricPressureLabel;
+ private System.Windows.Forms.Label outsideTempLabel;
+ private System.Windows.Forms.Label rainRateLabel;
+ private System.Windows.Forms.Label dailyRainfallLabel;
+ private System.Windows.Forms.SplitContainer splitContainer2;
+ private System.Windows.Forms.Label lblElAbsPos;
+ private System.Windows.Forms.Label lblAzAbsPos;
+ private System.Windows.Forms.Label lblCurrentAzOrientation;
+ private System.Windows.Forms.Label lblCurrentElOrientation;
+ private System.Windows.Forms.GroupBox groupBox8;
+ private System.Windows.Forms.Button runDiagScriptsButton;
+ private System.Windows.Forms.ComboBox diagnosticScriptCombo;
+ private System.Windows.Forms.GroupBox groupBox9;
+ private System.Windows.Forms.Label insideTempLabel;
+ private System.Windows.Forms.Label label23;
+ private System.Windows.Forms.Button button7;
+ private System.Windows.Forms.TabPage tabPage3;
+ private System.Windows.Forms.GroupBox Accelerometers;
+ private System.Windows.Forms.Button ElevationLimitSwitch90;
+ private System.Windows.Forms.Button ElivationLimitSwitch0;
+ private System.Windows.Forms.Label label3;
private System.Windows.Forms.Label label22;
+ private System.Windows.Forms.GroupBox WeatherStation;
+ private System.Windows.Forms.GroupBox MotorTemperatureSensors;
+ private System.Windows.Forms.Button ElMotTempSensOverride;
+ private System.Windows.Forms.Label label29;
+ private System.Windows.Forms.Button AzMotTempSensOverride;
+ private System.Windows.Forms.Label label28;
+ private System.Windows.Forms.GroupBox GatesSensors;
+ private System.Windows.Forms.Button MGOverride;
+ private System.Windows.Forms.Label label27;
+ private System.Windows.Forms.Button WSOverride;
+ private System.Windows.Forms.Label label24;
+ private System.Windows.Forms.SplitContainer splitContainer1;
+ private System.Windows.Forms.GroupBox groupBox14;
+ private System.Windows.Forms.Button farTempConvert;
+ private System.Windows.Forms.Button celTempConvert;
+ private System.Windows.Forms.Label InsideTempUnits;
+ private System.Windows.Forms.Label rainRateUnits;
+ private System.Windows.Forms.Label pressUnits;
+ private System.Windows.Forms.Label dailyRainfallUnits;
+ private System.Windows.Forms.Label outTempUnits;
+ private System.Windows.Forms.Label label35;
+ private System.Windows.Forms.Label windSpeedUnits;
+ private System.Windows.Forms.Label label32;
+ private System.Windows.Forms.Label label34;
+ private System.Windows.Forms.Label AZTempUnitLabel;
+ private System.Windows.Forms.Label ElTempUnitLabel;
+ private System.Windows.Forms.TabPage tabPage4;
+ private System.Windows.Forms.TabPage tabPage5;
+ private System.Windows.Forms.Label lblDCGain;
+ private System.Windows.Forms.Label DCGainVal;
+ private System.Windows.Forms.Label lblIFGain;
+ private System.Windows.Forms.Label IFGainVal;
+ private System.Windows.Forms.Label lblBandwidth;
+ private System.Windows.Forms.Label BandwidthVal;
+ private System.Windows.Forms.Label lblOffsetVoltage;
+ private System.Windows.Forms.Label OffsetVoltageVal;
+ private System.Windows.Forms.Label lblIntegrationStep;
+ private System.Windows.Forms.Label IntegrationStepVal;
+ private System.Windows.Forms.TextBox consoleLogBox;
+ private System.Windows.Forms.DataVisualization.Charting.Chart spectraCyberScanChart;
+ private System.Windows.Forms.Label lblFrequency;
+ private System.Windows.Forms.Label frequencyVal;
+ private System.Windows.Forms.Label lblModeType;
+ private System.Windows.Forms.Label spectraModeTypeVal;
+ private System.Windows.Forms.GroupBox SensorNetworkSensorInitialization;
+ private System.Windows.Forms.GroupBox SoftwareStopsThresholdGroup;
+ private System.Windows.Forms.GroupBox grpProximitySensors;
+ private System.Windows.Forms.Button btnElevationMotorAccelerometerOverride;
+ private System.Windows.Forms.Button btnAzimuthMotorAccelerometerOverride;
+ private System.Windows.Forms.Label label4;
+ private System.Windows.Forms.Label label21;
+ private System.Windows.Forms.Button btnCounterbalanceMotorAccelerometerOverride;
+ private System.Windows.Forms.Label label33;
+ private System.Windows.Forms.Button UpdateSensorInitiliazation;
+ private System.Windows.Forms.CheckBox AzimuthEncoder;
+ private System.Windows.Forms.CheckBox ElevationEncoder;
+ private System.Windows.Forms.CheckBox CounterbalanceAccelerometer;
+ private System.Windows.Forms.CheckBox ElevationAccelerometer;
+ private System.Windows.Forms.CheckBox AzimuthAccelerometer;
+ private System.Windows.Forms.CheckBox AzimuthTemperature1;
+ private System.Windows.Forms.CheckBox ElevationTemperature1;
+ private System.Windows.Forms.GroupBox Encoders;
+ private System.Windows.Forms.Button btnElevationAbsoluteEncoder;
+ private System.Windows.Forms.Button btnAzimuthAbsoluteEncoder;
+ private System.Windows.Forms.Label ElecationAbsoluteEncoder_lbl;
+ private System.Windows.Forms.Label AzimuthAbsoluteEncoder_lbl;
+ private System.Windows.Forms.Label lblSNStatus;
+ private System.Windows.Forms.GroupBox grpMcuStatus;
+ private System.Windows.Forms.Label lblMCUStatus;
+ private System.Windows.Forms.Label lblMCUStatusText;
+ private System.Windows.Forms.Label lblMCUErrors;
+ private System.Windows.Forms.Button btnResetMcuErrors;
+ private System.Windows.Forms.GroupBox grpAccelerometerSensorData;
+ private System.Windows.Forms.Label label45;
+ private System.Windows.Forms.Label label38;
+ private System.Windows.Forms.Label label46;
+ private System.Windows.Forms.Label label48;
+ private System.Windows.Forms.Panel pnlCounterbalanceAccelerometer;
+ private System.Windows.Forms.Label label50;
+ private System.Windows.Forms.Label label37;
+ private System.Windows.Forms.Label label49;
+ private System.Windows.Forms.Panel pnlElevationMotorAccelerometer;
+ private System.Windows.Forms.Label label47;
+ private System.Windows.Forms.Label label36;
+ private System.Windows.Forms.Panel pnlAzimuthMotorAccelerometer;
+ private System.Windows.Forms.GroupBox grpSensorData;
+ private System.Windows.Forms.Label lbGateStat;
+ private System.Windows.Forms.Label lbEstopStat;
+ private System.Windows.Forms.Label label31;
+ private System.Windows.Forms.Label label30;
+ private System.Windows.Forms.Label lblAzHome1;
+ private System.Windows.Forms.Label lblElLimStatus2;
+ private System.Windows.Forms.Label lblElLimStatus1;
+ private System.Windows.Forms.Label lblElHome;
+ private System.Windows.Forms.Label lblELHomeStatus;
+ private System.Windows.Forms.Label lblAzHomeStatus1;
+ private System.Windows.Forms.Label lblAzLimit1;
+ private System.Windows.Forms.Label lblAzLimit2;
+ private System.Windows.Forms.DataVisualization.Charting.Chart elevationAccChart;
+ private System.Windows.Forms.DataVisualization.Charting.Chart counterBalanceAccChart;
+ private System.Windows.Forms.DataVisualization.Charting.Chart azimuthAccChart;
+ private System.Windows.Forms.Label lblCbDisabled;
+ private System.Windows.Forms.Label lblElDisabled;
+ private System.Windows.Forms.Label lblAzDisabled;
+ private System.Windows.Forms.Label lblInitTimeout;
+ private System.Windows.Forms.Label lblDataTimeout;
+ private System.Windows.Forms.TextBox txtDataTimeout;
+ private System.Windows.Forms.TextBox txtInitTimeout;
+ private System.Windows.Forms.ToolTip DataTimeoutValidation;
+ private System.Windows.Forms.ToolTip InitTimeoutValidation;
+ private System.Windows.Forms.Label label25;
+ private System.Windows.Forms.Label label26;
+ private System.Windows.Forms.TextBox LowerSWStopsLimitText;
+ private System.Windows.Forms.TextBox UpperSWStopsLimitText;
+ private System.Windows.Forms.Button UpdateSWStopsButton;
+ private System.Windows.Forms.Label SWStopLowerLabel;
+ private System.Windows.Forms.Label SWStopUpperLabel;
+ private System.Windows.Forms.ToolTip UpperLimitToolTip;
+ private System.Windows.Forms.ToolTip LowerLimitToolTip;
}
}
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/GUI/DiagnosticsForm.cs b/ControlRoomApplication/ControlRoomApplication/GUI/DiagnosticsForm.cs
index 7ddb772d..dec1149b 100644
--- a/ControlRoomApplication/ControlRoomApplication/GUI/DiagnosticsForm.cs
+++ b/ControlRoomApplication/ControlRoomApplication/GUI/DiagnosticsForm.cs
@@ -1,97 +1,125 @@
using ControlRoomApplication.Entities;
using ControlRoomApplication.Simulators.Hardware;
using System.Windows.Forms;
+using System.IO;
using System.Drawing;
using ControlRoomApplication.Simulators.Hardware.AbsoluteEncoder;
using ControlRoomApplication.Simulators.Hardware.MCU;
using ControlRoomApplication.Controllers;
-using ControlRoomApplication.Controllers.BlkHeadUcontroler;
using ControlRoomApplication.Database;
+using ControlRoomApplication.Constants;
+using System;
+using ControlRoomApplication.Main;
+using ControlRoomApplication.Controllers.Sensors;
+using ControlRoomApplication.Controllers.Communications;
+using System.Threading;
+using System.ComponentModel;
+using ControlRoomApplication.Util;
+using System.Linq;
+using ControlRoomApplication.Controllers.SensorNetwork;
+using System.Drawing.Printing;
+using System.Threading.Tasks;
+using ControlRoomApplication.Validation;
+using ControlRoomApplication.Controllers.PLCCommunication.PLCDrivers.MCUManager;
namespace ControlRoomApplication.GUI
{
public partial class DiagnosticsForm : Form
{
private ControlRoom controlRoom;
- EncoderReader encoderReader = new EncoderReader("192.168.7.2",1602);
ControlRoomApplication.Entities.Orientation azimuthOrientation = new ControlRoomApplication.Entities.Orientation();
-
+ private RadioTelescopeController rtController { get; set; }
- private SimulationMCU mtrCtrl;
- private int timerTick = 0;
- private int demoIndex = 0;
- //private PLC PLC; This needs to be defined once I can get find the currect import
+ // Thread that monitors the overrides, and updates the buttons as necessary
+ BackgroundWorker SensorSettingsThread;
- //TemperatureSensor myTemp = new TemperatureSensor();
- FakeTempSensor myTemp = new FakeTempSensor();
+ FakeEncoderSensor myEncoder = new FakeEncoderSensor();
/***********DEMO MODE VARIABLES**************/
- private double[] azEncDemo = {0, 0.2, 0.4, 0.6, 0.8, 1, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4, 4.6, 4.8, 5.0, 5.2, 5.4, 5.6, 5.8, 6.0, 6.2, 6.4, 6.6, 6.8, 7.0, 7.2, 7.4, 7.6, 7.8, 8.0, 8.2, 8.4, 8.6, 8.8, 9.0, 9.2, 9.4, 9.6, 9.8, 10.0, 10.2, 10.4, 10.6, 10.8, 11.0, 11.2, 11.4, 11.6, 11.8, 12.0, 12.2, 12.4, 12.6, 12.8, 13.0, 13.2, 13.4, 13.6, 13.8, 14.0, 14.2, 14.4, 14.6, 14.8, 15.0, 15.2, 15.4, 15.6, 15.8, 16.0 }; //12 11.3 ticks per degree
- private double[] elEncDemo = { 0, 0.2, 0.4, 0.6, 0.8, 1, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4, 4.6, 4.8, 5.0, 5.2, 5.4, 5.6, 5.8, 6.0, 6.2, 6.4, 6.6, 6.8, 7.0, 7.2, 7.4, 7.6, 7.8, 8.0, 8.2, 8.4, 8.6, 8.8, 9.0, 9.2, 9.4, 9.6, 9.8, 10.0, 10.2, 10.4, 10.6, 10.8, 11.0, 11.2, 11.4, 11.6, 11.8, 12.0, 12.2, 12.4, 12.6, 12.8, 13.0, 13.2, 13.4, 13.6, 13.8, 14.0, 14.2, 14.4, 14.6, 14.8, 15.0, 15.2, 15.4, 15.6, 15.8, 16.0 }; //10 bits of precision, 2.8
-
-
+ DateTime currentEncodDate = DateTime.Now;
+ private bool graphClear = true;
-
-
/***********DEMO MODE VARIABLES END*********/
-
-
+ // Encoder Variables
double _azEncoderDegrees = 0;
double _elEncoderDegrees = 0;
double _elevationTemp = 0;
- double _azimuthTemp = 0;
int _azEncoderTicks = 0;
int _elEncoderTicks = 0;
-
-
- bool warningSent = false;
- bool shutdownSent = false;
-
- private int rtId;
- private double az;
- private double el;
- private string[] statuses = { "Offline", "Offline", "Offline", "Offline" };
- private static readonly log4net.ILog logger =
- log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
- ///
- /// Initializes the diagnostic form based off of the specified configuration.
- ///
- ///
+ // Azimuth Limit Switch Variables
+ bool _azCCWLimitChange = false;
+ bool _azCWLimitOld = false;
-
+ bool _azCWLimitChange = false;
+ bool _azCCWLimitOld = false;
- public DiagnosticsForm()
- {
- InitializeComponent();
+ // Elevation Limit Switch Variables
+ bool _elLowerLimitChange = false;
+ bool _elLowerLimitOld = false;
+ bool _elUpperLimitChange = false;
+ bool _elUpperLimitOld = false;
- az = 0.0;
- el = 0.0;
- timer1.Start();
- logger.Info("DiagnosticsForm Initalized");
- }
+ // Azimuth Proximity Sensor Variables
+ bool _azCCWProxOld = false;
+ bool _azCCWProxChange = false;
+
+ bool _azCWProxOld = false;
+ bool _azCWProxChange = false;
+
+ bool _azCloserUpperProx = false;
+
+ // Elevation Proximity Sensor Variables
+ bool _elLowerProxOld = false;
+ bool _elLowerProxChange = false;
+
+ bool _elUpperProxOld = false;
+ bool _elUpperProxChange = false;
+
+ // Alert Flags
+ bool fahrenheit = true;
+
+ // Validation for sensor timeouts
+ bool DataTimeoutValid;
+ bool InitTimeoutValid;
+
+ //validation for software stop thresholds
+ bool ValidUpperSWStopLimit;
+ bool ValidLowerSWStopLimit;
+
+ private int rtId;
+
+ private Acceleration[] azOld;
+ private Acceleration[] elOld;
+ private Acceleration[] cbOld;
+
+ // Config file for the sensor network server to use
+ SensorNetworkConfig SensorNetworkConfig;
+
+ // This is being passed through so the Weather Station override bool can be modified
+ private readonly MainForm mainF;
+
+ private string[] statuses = { "Offline", "Offline", "Offline", "Offline" };
+ private static readonly log4net.ILog logger =
+ log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
///
/// Initializes the diagnostic form based off of the specified configuration.
///
///
- public DiagnosticsForm(ControlRoom controlRoom, int rtId)
+ public DiagnosticsForm(ControlRoom controlRoom, int new_rtId, MainForm mainF)
{
InitializeComponent();
- az = 0.0;
- el = 0.0;
-
-
-
+ this.controlRoom = controlRoom;
+ rtId = new_rtId;
- this.controlRoom = controlRoom;
-
+ this.mainF = mainF;
+ rtController = controlRoom.RadioTelescopeControllers.Find(x => x.RadioTelescope.Id == rtId);
- this.rtId = rtId;
dataGridView1.ColumnCount = 2;
dataGridView1.Columns[0].HeaderText = "Hardware";
@@ -108,35 +136,91 @@ public DiagnosticsForm(ControlRoom controlRoom, int rtId)
dataGridView1.Rows.Add(mcuRow);
dataGridView1.Update();
- SetCurrentAzimuthAndElevation();
- logger.Info("DiagnosticsForm Initalized");
+ //MCU_Statui.ColumnCount = 2;
+ //MCU_Statui.Columns[0].HeaderText = "Status name";
+ //MCU_Statui.Columns[1].HeaderText = "value";
+
+ SetCurrentWeatherData();
+ runDiagScriptsButton.Enabled = false;
+
+ // Updates the override buttons so they reflect what the actual override values are
+ bool currMain = rtController.overrides.overrideGate;
+ bool currWS = controlRoom.weatherStationOverride;
+ bool currAZ = rtController.overrides.overrideAzimuthMotTemp;
+ bool currEL = rtController.overrides.overrideElevatMotTemp;
+ bool currElProx0 = rtController.overrides.overrideElevatProx0;
+ bool currElProx90 = rtController.overrides.overrideElevatProx90;
+ bool currAzimuthAbsEncoder = rtController.overrides.overrideAzimuthAbsEncoder;
+ bool currElevationAbsEncoder = rtController.overrides.overrideElevationAbsEncoder;
+ bool currAzimuthAccelerometer = rtController.overrides.overrideAzimuthAccelerometer;
+ bool currElevationAccelerometer = rtController.overrides.overrideElevationAccelerometer;
+ bool currCounterbalanceAccelerometer = rtController.overrides.overrideCounterbalanceAccelerometer;
+ UpdateOverrideButtons(currMain, currWS, currAZ, currEL, currElProx0, currElProx90,
+ currAzimuthAbsEncoder, currElevationAbsEncoder, currAzimuthAccelerometer, currElevationAccelerometer, currCounterbalanceAccelerometer);
+
+ SensorSettingsThread = new BackgroundWorker();
+ SensorSettingsThread.DoWork += new DoWorkEventHandler(SensorSettingsRoutine);
+ SensorSettingsThread.RunWorkerAsync();
+
+ //Initialize Color
+ celTempConvert.BackColor = System.Drawing.Color.DarkGray;
+ farTempConvert.BackColor = System.Drawing.Color.LimeGreen;
+
+ lblSNStatus.Text = "";
+
+ // Set sensor initialization checkboxes to reflect what is stored in the database
+ SensorNetworkConfig = rtController.RadioTelescope.SensorNetworkServer.InitializationClient.SensorNetworkConfig;
+
+ AzimuthTemperature1.Checked = SensorNetworkConfig.AzimuthTemp1Init;
+ ElevationTemperature1.Checked = SensorNetworkConfig.ElevationTemp1Init;
+ AzimuthAccelerometer.Checked = SensorNetworkConfig.AzimuthAccelerometerInit;
+ ElevationAccelerometer.Checked = SensorNetworkConfig.ElevationAccelerometerInit;
+ CounterbalanceAccelerometer.Checked = SensorNetworkConfig.CounterbalanceAccelerometerInit;
+ ElevationEncoder.Checked = SensorNetworkConfig.ElevationEncoderInit;
+ AzimuthEncoder.Checked = SensorNetworkConfig.AzimuthEncoderInit;
+ txtDataTimeout.Text = "" + (double)SensorNetworkConfig.TimeoutDataRetrieval / 1000;
+ txtInitTimeout.Text = "" + (double)SensorNetworkConfig.TimeoutInitialization / 1000;
+
+ //get the current software stops thresholds
+ //get the current software stops thresholds
+ LowerSWStopsLimitText.Text = "" + rtController.RadioTelescope.minElevationDegrees.ToString("0.00");
+ UpperSWStopsLimitText.Text = "" + rtController.RadioTelescope.maxElevationDegrees.ToString("0.00");
+
+ // Set default values for timeout validation
+ DataTimeoutValid = true;
+ InitTimeoutValid = true;
+
+ azOld = new Acceleration[0];
+ elOld = new Acceleration[0];
+ cbOld = new Acceleration[0];
+
+ logger.Info(Utilities.GetTimeStamp() + ": DiagnosticsForm Initalized");
}
- private void SetCurrentAzimuthAndElevation()
+ private void SetCurrentWeatherData()
{
- label3.Text = controlRoom.RadioTelescopeControllers[rtId].GetCurrentOrientation().Azimuth.ToString("0.00");
- label4.Text = controlRoom.RadioTelescopeControllers[rtId].GetCurrentOrientation().Elevation.ToString("0.00");
-
-
+ windSpeedLabel.Text = Math.Round(controlRoom.WeatherStation.GetWindSpeed(), 2).ToString();
+ windDirLabel.Text = controlRoom.WeatherStation.GetWindDirection();
+ dailyRainfallLabel.Text = Math.Round(controlRoom.WeatherStation.GetDailyRain(), 2).ToString();
+ rainRateLabel.Text = Math.Round(controlRoom.WeatherStation.GetRainRate(), 2).ToString();
+ //outsideTempLabel.Text = Math.Round(controlRoom.WeatherStation.GetOutsideTemp(), 2).ToString();
+ //insideTempLabel.Text = Math.Round(controlRoom.WeatherStation.GetInsideTemp(), 2).ToString();
+ barometricPressureLabel.Text = Math.Round(controlRoom.WeatherStation.GetBarometricPressure(), 2).ToString();
}
///
/// Gets and displays the current statuses of the hardware components for the specified configuration.
///
private void GetHardwareStatuses() {
- if(controlRoom.RadioTelescopes[rtId].SpectraCyberController.IsConsideredAlive()) {
+ if (rtController.RadioTelescope.SpectraCyberController.IsConsideredAlive()) {
statuses[0] = "Online";
}
- if(controlRoom.WeatherStation.IsConsideredAlive()) {
+ if (controlRoom.WeatherStation.IsConsideredAlive()) {
statuses[1] = "Online";
}
}
-
-
-
-
public delegate void SetStartTimeTextCallback(string text);
public void SetStartTimeText(string text)
{
@@ -186,278 +270,1136 @@ public void SetApptStatusText(string text)
* ************************************************************/
private void timer1_Tick(object sender, System.EventArgs e)
{
+ double currWindSpeed = controlRoom.WeatherStation.GetWindSpeed();//wind speed
+
+ //double testVal = rtController.RadioTelescope.Encoders.GetCurentOrientation().Azimuth;
- double elevationTemperature = 0.0;
- double azimuthTemperature = 0.0;
- //int ticks = azEncoder.CurrentPositionTicks;
+ Entities.Orientation currAbsOrientation = rtController.GetAbsoluteOrientation();
- //Read actual encoder values
- // _azEncoderDegrees = Controllers.BlkHeadUcontroler.EncoderReader.GetCurentOrientation().Azimuth;
- // _elEncoderDegrees = Controllers.BlkHeadUcontroler.EncoderReader.GetCurentOrientation().Elevation;
+ _azEncoderDegrees = currAbsOrientation.Azimuth;
+ _elEncoderDegrees = currAbsOrientation.Elevation;
+ lblAzAbsPos.Text = Math.Round(_azEncoderDegrees, 2).ToString();
+ lblElAbsPos.Text = Math.Round(_elEncoderDegrees, 2).ToString();
- _azEncoderDegrees = controlRoom.RadioTelescopeControllers[rtId].GetAbsoluteOrientation().Azimuth;//.GetCurrentOrientation().Azimuth;
- _elEncoderDegrees = controlRoom.RadioTelescopeControllers[rtId].GetAbsoluteOrientation().Elevation; //GetCurrentOrientation().Elevation;
+ timer1.Interval = 200;
+ Temperature[] ElMotTemps = rtController.RadioTelescope.SensorNetworkServer.CurrentElevationMotorTemp;
+ Temperature[] AzMotTemps = rtController.RadioTelescope.SensorNetworkServer.CurrentAzimuthMotorTemp;
- elevationTemperature = DatabaseOperations.GetCurrentTemp( SensorLocationEnum.EL_MOTOR ).temp;
- azimuthTemperature = DatabaseOperations.GetCurrentTemp( SensorLocationEnum.AZ_MOTOR ).temp;
+ // these come in as celsius
+ double ElMotTemp = ElMotTemps[ElMotTemps.Length - 1].temp;
+ double AzMotTemp = AzMotTemps[AzMotTemps.Length - 1].temp;
- this.label22.Text = (!controlRoom.RadioTelescopeControllers[rtId].finished_exicuting_move()).ToString();
+ float insideTemp = controlRoom.WeatherStation.GetInsideTemp();
+ float outsideTemp = controlRoom.WeatherStation.GetOutsideTemp();
- timer1.Interval = 200;
-
+ double insideTempCel = (insideTemp - 32) * (5.0 / 9);
+ double outsideTempCel = (outsideTemp - 32) * (5.0 / 9);
- if (selectDemo.Checked == true)
- {
- elevationTemperature = myTemp.GetElevationTemperature();
- azimuthTemperature = myTemp.GetAzimuthTemperature();
+ // fahrenheit conversion
+ double ElMotTempFahrenheit = (ElMotTemp * (9.0 / 5.0)) + 32;
+ double AzMotTempFahrenheit = (AzMotTemp * (9.0 / 5.0)) + 32;
- if(demoIndex < 79)
- {
- _azEncoderDegrees = azEncDemo[demoIndex++];
- _elEncoderDegrees = elEncDemo[demoIndex];
+ if (controlRoom.RTControllerManagementThreads.Count > 0 && controlRoom.RTControllerManagementThreads[0].AppointmentToDisplay != null)
+ {
+ Appointment appt = controlRoom.RTControllerManagementThreads[0].AppointmentToDisplay;
+ statusTextBox.Text = appt.status.ToString();
+ endTimeTextBox.Text = appt.end_time.ToString();
+ startTimeTextBox.Text = appt.start_time.ToString();
+ }
+ else
+ {
+ statusTextBox.Text = "";
+ endTimeTextBox.Text = "";
+ startTimeTextBox.Text = "";
+ }
+ //Celsius
+ if (fahrenheit == false)
+ {
+ InsideTempUnits.Text = "Celsius";
+ outTempUnits.Text = "Celsius";
+ AZTempUnitLabel.Text = "Celsius";
+ ElTempUnitLabel.Text = "Celsius";
+ outsideTempLabel.Text = Math.Round(insideTempCel, 2).ToString();
+ insideTempLabel.Text = Math.Round(outsideTempCel, 2).ToString();
+
+ if (SensorNetworkConfig.ElevationTemp1Init)
+ {
+ fldElTemp.Text = Math.Round(ElMotTemp, 2).ToString();
+ }
+ else
+ {
+ fldElTemp.Text = "--";
+ }
- _azEncoderTicks = (int)(_azEncoderDegrees * 11.38);
- _elEncoderTicks = (int)(_elEncoderDegrees * 2.8);
+ if (SensorNetworkConfig.AzimuthTemp1Init)
+ {
+ fldAzTemp.Text = Math.Round(AzMotTemp, 2).ToString();
+ }
+ else
+ {
+ fldAzTemp.Text = "--";
+ }
+ }
+ //fahrenheit
+ else if (fahrenheit == true)
+ {
+ InsideTempUnits.Text = "Fahrenheit";
+ outTempUnits.Text = "Fahrenheit";
+ AZTempUnitLabel.Text = "Fahrenheit";
+ ElTempUnitLabel.Text = "Fahrenheit";
+ outsideTempLabel.Text = Math.Round(controlRoom.WeatherStation.GetOutsideTemp(), 2).ToString();
+ insideTempLabel.Text = Math.Round(controlRoom.WeatherStation.GetInsideTemp(), 2).ToString();
+
+ if (SensorNetworkConfig.ElevationTemp1Init)
+ {
+ fldElTemp.Text = Math.Round(ElMotTempFahrenheit, 2).ToString();
}
else
{
- demoIndex = 0;
+ fldElTemp.Text = "--";
}
-
+ if (SensorNetworkConfig.AzimuthTemp1Init)
+ {
+ fldAzTemp.Text = Math.Round(AzMotTempFahrenheit, 2).ToString();
+ }
+ else
+ {
+ fldAzTemp.Text = "--";
+ }
}
-
-
- fldElTemp.Text = elevationTemperature.ToString();
- fldAzTemp.Text = azimuthTemperature.ToString();
- lblAzEncoderDegrees.Text = _azEncoderDegrees.ToString();
- lblElEncoderDegrees.Text = _elEncoderDegrees.ToString();
+
+ // Encoder Position in both degrees and motor ticks
+ lblAzEncoderDegrees.Text = Math.Round(_azEncoderDegrees, 2).ToString();
lblAzEncoderTicks.Text = _azEncoderTicks.ToString();
+
+ // lblElEncoderDegrees.Text = _elEncoderDegrees.ToString();
+ lblElEncoderDegrees.Text =Math.Round(_elEncoderDegrees, 2).ToString();
lblElEncoderTicks.Text = _elEncoderTicks.ToString();
+ // Proximity and Limit Switches
+ lblElLimStatus1.Text = rtController.RadioTelescope.PLCDriver.limitSwitchData.Elevation_Lower_Limit.ToString();
+ lblElLimStatus2.Text = rtController.RadioTelescope.PLCDriver.limitSwitchData.Elevation_Upper_Limit.ToString();
+
+ lblAzHomeStatus1.Text = rtController.RadioTelescope.PLCDriver.homeSensorData.Azimuth_Home_One.ToString();
+ lblELHomeStatus.Text = rtController.RadioTelescope.PLCDriver.homeSensorData.Elevation_Home.ToString();
+
+ lbEstopStat.Text = rtController.RadioTelescope.PLCDriver.plcInput.Estop.ToString();
+ lbGateStat.Text = rtController.RadioTelescope.PLCDriver.plcInput.Gate_Sensor.ToString();
+
+ GetHardwareStatuses();
+
+ SetCurrentWeatherData();
+
+ dataGridView1.Update();
+
+ // Spectra Cyber Tab Updates
+ spectraModeTypeVal.Text = rtController.RadioTelescope.SpectraCyberController.configVals.spectraCyberMode.ToString();
+
+ BandwidthVal.Text = rtController.RadioTelescope.SpectraCyberController.configVals.bandwidth.GetValue();
+ frequencyVal.Text = rtController.RadioTelescope.SpectraCyberController.configVals.frequency.ToString();
+ IFGainVal.Text = rtController.RadioTelescope.SpectraCyberController.configVals.IFGain.ToString();
+
+ if(rtController.RadioTelescope.SpectraCyberController.configVals.spectraCyberMode == SpectraCyberModeTypeEnum.SPECTRAL)
+ DCGainVal.Text = rtController.RadioTelescope.SpectraCyberController.configVals.specGain.GetValue();
+ else if(rtController.RadioTelescope.SpectraCyberController.configVals.spectraCyberMode == SpectraCyberModeTypeEnum.CONTINUUM)
+ DCGainVal.Text = rtController.RadioTelescope.SpectraCyberController.configVals.contGain.GetValue();
+
+ IntegrationStepVal.Text = rtController.RadioTelescope.SpectraCyberController.configVals.integrationStep.ToString();
+
+ OffsetVoltageVal.Text = rtController.RadioTelescope.SpectraCyberController.configVals.offsetVoltage.ToString();
+
+ // Spectra Cyber Graph Update
+ if (rtController.RadioTelescope.SpectraCyberController.Schedule.GetMode() == SpectraCyberScanScheduleMode.CONTINUOUS_SCAN
+ || rtController.RadioTelescope.SpectraCyberController.Schedule.GetMode() == SpectraCyberScanScheduleMode.SCHEDULED_SCAN
+ || rtController.RadioTelescope.SpectraCyberController.Schedule.GetMode() == SpectraCyberScanScheduleMode.SINGLE_SCAN)
+ {
+ if (rtController.RadioTelescope.SpectraCyberController.configVals.spectraCyberMode == SpectraCyberModeTypeEnum.SPECTRAL)
+ {
+ if(graphClear == true)
+ {
+ spectraCyberScanChart.Series.Clear();
+ spectraCyberScanChart.Series.Add("Spectral");
+ spectraCyberScanChart.Series["Spectral"].ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Spline;
+ spectraCyberScanChart.ChartAreas["ChartArea1"].AxisX.Title = "Frequency";
+ graphClear = false;
+ }
+
+ double intensity = rtController.RadioTelescope.SpectraCyberController.configVals.rfData;
+ double frequency = rtController.RadioTelescope.SpectraCyberController.configVals.bandscan;
+
+ spectraCyberScanChart.Series["Spectral"].Points.AddXY(frequency, intensity);
+
+ if (frequency >= rtController.RadioTelescope.SpectraCyberController.configVals.frequency / 2)
+ spectraCyberScanChart.Series["Spectral"].Points.Clear();
+ }
+ else if (rtController.RadioTelescope.SpectraCyberController.configVals.spectraCyberMode == SpectraCyberModeTypeEnum.CONTINUUM)
+ {
+ if (graphClear == true)
+ {
+ spectraCyberScanChart.Series.Clear();
+ spectraCyberScanChart.Series.Add("Continuum");
+ spectraCyberScanChart.Series["Continuum"].ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Spline;
+ spectraCyberScanChart.ChartAreas["ChartArea1"].AxisX.Title = "Time";
+ graphClear = false;
+ }
+
+ double intensity = rtController.RadioTelescope.SpectraCyberController.configVals.rfData;
+ double time = rtController.RadioTelescope.SpectraCyberController.configVals.scanTime;
+
+ spectraCyberScanChart.Series["Continuum"].Points.AddXY(time, intensity);
+
+ }
+ }
+ else
+ {
+ graphClear = true;
+ }
+
+ // Update MCU error status
+
+ // First retrieve errors
+ String errors = string.Join("\n", rtController.RadioTelescope.PLCDriver.CheckMCUErrors().
+ Select(s =>
+ s.Item1.ToString() + ": " + s.Item2.ToString()
+ ).ToArray());
+
+ if(!errors.Equals(""))
+ {
+ lblMCUStatus.ForeColor = Color.Red;
+ lblMCUStatus.Text = "Contains Errors";
+
+ }
+ else
+ {
+ lblMCUStatus.ForeColor = Color.Green;
+ lblMCUStatus.Text = "Running";
+ }
+
+ // Display errors
+ lblMCUErrors.Text = errors;
+
+ // Console Log Output Update
+ consoleLogBox.Text = mainF.log.loggerQueue;
+
+ if (!consoleLogBox.Focused)
+ {
+ consoleLogBox.SelectionStart = consoleLogBox.TextLength;
+ consoleLogBox.ScrollToCaret();
+ }
+
+ // FFT transformations -- currently not in use
+ //double[] fftX = FftSharp.Transform.FFTpower(eleAccelerometerX);
+ //double[]fft
+ //double SAMPLE_RATE = 0.8;
+
+ // Create an array of frequencies for each point of the FFT
+ //double[] freqs = FftSharp.Transform.FFTfreq(SAMPLE_RATE , fftX.Length);
+
- /*** Temperature Logic Start***/
- if(elevationTemperature <= 79 && azimuthTemperature <= 79)
+ // Azimuth Accelerometer Chart /////////////////////////////////////////////
+ if (SensorNetworkConfig.AzimuthAccelerometerInit)
{
- warningLabel.Visible = false;
- lblShutdown.Visible = false;
- fanLabel.Visible = false;
- warningSent = false;
- shutdownSent = false;
+ lblAzDisabled.Visible = false;
+ Acceleration[] azimuthAccel = rtController.RadioTelescope.SensorNetworkServer.CurrentAzimuthMotorAccl;
+ azimuthAccChart.ChartAreas[0].AxisX.Minimum = double.NaN;
+ azimuthAccChart.ChartAreas[0].AxisX.Maximum = double.NaN;
+
+ if (azOld != null && Acceleration.SequenceEquals(azOld, azimuthAccel))
+ {
+ for (int i = 0; i < azimuthAccel.Length; i++)
+ {
+ azimuthAccChart.Series["x"].Points.AddY(azimuthAccel[i].x);
+ azimuthAccChart.Series["y"].Points.AddY(azimuthAccel[i].y);
+ azimuthAccChart.Series["z"].Points.AddY(azimuthAccel[i].z);
+ azimuthAccChart.Series["accel"].Points.AddY(azimuthAccel[i].acc);
+
+
+ if (azimuthAccChart.Series["x"].Points.Count > 500)
+ {
+ azimuthAccChart.Series["x"].Points.RemoveAt(0);
+ azimuthAccChart.Series["y"].Points.RemoveAt(0);
+ azimuthAccChart.Series["z"].Points.RemoveAt(0);
+ azimuthAccChart.Series["accel"].Points.RemoveAt(0);
+ }
+ azimuthAccChart.ChartAreas[0].RecalculateAxesScale();
+ }
+ }
+
+ azOld = azimuthAccel;
+
}
- else if(elevationTemperature > 79 && elevationTemperature < 100 || azimuthTemperature > 79 && azimuthTemperature < 100)
+ else
{
- if(warningSent == false)
+ // This all only needs to be executed once when it is reached. This if statement
+ // blocks these five lines from being executed during every single tick
+ if (!lblAzDisabled.Visible)
{
- warningLabel.Visible = true;
+ lblAzDisabled.Visible = true;
+ lblAzDisabled.Text = "Azimuth Motor Accelerometer Disabled";
+ azimuthAccChart.Series["x"].Points.Clear();
+ azimuthAccChart.Series["y"].Points.Clear();
+ azimuthAccChart.Series["z"].Points.Clear();
+ azimuthAccChart.Series["accel"].Points.Clear();
}
- else
+ }
+ ///////////////////////////////////////////////////////////////////////////////
+
+ // Elevation Accelerometer Chart /////////////////////////////////////////////
+ if (SensorNetworkConfig.ElevationAccelerometerInit)
+ {
+ lblElDisabled.Visible = false;
+ Acceleration[] eleAccel = rtController.RadioTelescope.SensorNetworkServer.CurrentElevationMotorAccl;
+
+ elevationAccChart.ChartAreas[0].AxisX.Minimum = double.NaN;
+ elevationAccChart.ChartAreas[0].AxisX.Maximum = double.NaN;
+
+ if (elOld != null && Acceleration.SequenceEquals(elOld, eleAccel))
{
- warningLabel.Visible = false;
+ for (int i = 0; i < eleAccel.Length; i++)
+ {
+ elevationAccChart.Series["x"].Points.AddY(eleAccel[i].x);
+ elevationAccChart.Series["y"].Points.AddY(eleAccel[i].y);
+ elevationAccChart.Series["z"].Points.AddY(eleAccel[i].z);
+ elevationAccChart.Series["accel"].Points.AddY(eleAccel[i].acc);
+
+
+ if (elevationAccChart.Series["x"].Points.Count > 500)
+ {
+ elevationAccChart.Series["x"].Points.RemoveAt(0);
+ elevationAccChart.Series["y"].Points.RemoveAt(0);
+ elevationAccChart.Series["z"].Points.RemoveAt(0);
+ elevationAccChart.Series["accel"].Points.RemoveAt(0); ;
+ }
+ elevationAccChart.ChartAreas[0].RecalculateAxesScale();
+ }
}
-
- lblShutdown.Visible = false;
- warningLabel.ForeColor = Color.Yellow;
- warningLabel.Text = "Warning Sent";
- warningSent = true;
+ elOld = eleAccel;
- fanLabel.Visible = true;
- fanLabel.ForeColor = Color.Blue;
- fanLabel.Text = "Fans On";
-
}
- else if(elevationTemperature >= 100 || azimuthTemperature >= 100)
+ else
+ {
+ // This all only needs to be executed once when it is reached. This if statement
+ // blocks these five lines from being executed during every single tick
+ if (!lblElDisabled.Visible)
+ {
+ lblElDisabled.Visible = true;
+ lblElDisabled.Text = "Elevation Motor Accelerometer Disabled";
+ elevationAccChart.Series["x"].Points.Clear();
+ elevationAccChart.Series["y"].Points.Clear();
+ elevationAccChart.Series["z"].Points.Clear();
+ elevationAccChart.Series["accel"].Points.Clear();
+ }
+ }
+ ///////////////////////////////////////////////////////////////////////////////
+
+ // CounterBalance Accelerometer Chart /////////////////////////////////////////////
+ if (SensorNetworkConfig.CounterbalanceAccelerometerInit)
{
- warningLabel.Visible = false;
+ lblCbDisabled.Visible = false;
+ Acceleration[] cbAccel = rtController.RadioTelescope.SensorNetworkServer.CurrentCounterbalanceAccl;
+ counterBalanceAccChart.ChartAreas[0].AxisX.Minimum = double.NaN;
+ counterBalanceAccChart.ChartAreas[0].AxisX.Maximum = double.NaN;
- if (shutdownSent == false)
+ if (cbOld != null && Acceleration.SequenceEquals(cbOld, cbAccel))
{
- lblShutdown.Visible = true;
+ for (int i = 0; i < cbAccel.Length; i++)
+ {
+ counterBalanceAccChart.Series["x"].Points.AddY(cbAccel[i].x);
+ counterBalanceAccChart.Series["y"].Points.AddY(cbAccel[i].y);
+ counterBalanceAccChart.Series["z"].Points.AddY(cbAccel[i].z);
+ counterBalanceAccChart.Series["accel"].Points.AddY(cbAccel[i].acc);
+
+
+ if (counterBalanceAccChart.Series["x"].Points.Count > 500)
+ {
+ counterBalanceAccChart.Series["x"].Points.RemoveAt(0);
+ counterBalanceAccChart.Series["y"].Points.RemoveAt(0);
+ counterBalanceAccChart.Series["z"].Points.RemoveAt(0);
+ counterBalanceAccChart.Series["accel"].Points.RemoveAt(0);
+ }
+ counterBalanceAccChart.ChartAreas[0].RecalculateAxesScale();
+ }
}
- else
+
+ cbOld = cbAccel;
+
+ }
+ else
+ {
+ // This all only needs to be executed once when it is reached. This if statement
+ // blocks these five lines from being executed during every single tick
+ if (!lblCbDisabled.Visible)
{
- lblShutdown.Visible = false;
+ lblCbDisabled.Visible = true;
+ lblCbDisabled.Text = "Counterbalance Accelerometer Disabled";
+ counterBalanceAccChart.Series["x"].Points.Clear();
+ counterBalanceAccChart.Series["y"].Points.Clear();
+ counterBalanceAccChart.Series["z"].Points.Clear();
+ counterBalanceAccChart.Series["accel"].Points.Clear();
}
-
- lblShutdown.ForeColor = Color.Red;
- lblShutdown.Text = "Shutdown Sent";
+ }
+ ///////////////////////////////////////////////////////////////////////////////
+
+ // Update the Sensor Network status
+ lblSNStatus.Text = "Status:\n" + rtController.RadioTelescope.SensorNetworkServer.Status.ToString();
+ }
+
+ private void DiagnosticsForm_Load(object sender, System.EventArgs e)
+ {
+
+ }
+
+ private void btnTest_Click(object sender, System.EventArgs e)
+ {
+ double temperature = 0;
+ }
+
+ private void btnAddOneTemp_Click(object sender, System.EventArgs e)
+ {
+ _elevationTemp += 1;
+ }
+
+ private void btnAddFiveTemp_Click(object sender, System.EventArgs e)
+ {
+ _elevationTemp += 5;
+ }
+
+ private void button2_Click(object sender, System.EventArgs e)
+ {
+ _elevationTemp -= 5;
+ }
- shutdownSent = true;
+ private void button4_Click(object sender, System.EventArgs e)
+ {
+ _azEncoderDegrees += 1;
+
+ }
+
+ private void button5_Click(object sender, System.EventArgs e)
+ {
+ _azEncoderDegrees += 5;
+ }
+
+ private void btnSubtractOneEncoder_Click(object sender, System.EventArgs e)
+ {
+ _azEncoderDegrees -= 1;
- fanLabel.Visible = true;
- fanLabel.ForeColor = Color.Blue;
- fanLabel.Text = "Fans Stay On";
+ }
+
+ private void btnSubtractFiveEncoder_Click(object sender, System.EventArgs e)
+ {
+ _azEncoderDegrees -= 5;
+ }
+
+ private void btnAddXEncoder_Click(object sender, System.EventArgs e)
+ {
+ double encVal; //encoder value
+ if (double.TryParse(txtCustEncoderVal.Text, out encVal))
+ {
+ _azEncoderDegrees += encVal;
}
else
{
- warningLabel.Visible = false;
- warningLabel.ForeColor = Color.Black;
- warningLabel.Text = "";
+ MessageBox.Show("Invalid entry in Encoder field", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ }
+ }
+
+ private void btnSubtractXEncoder_Click(object sender, System.EventArgs e)
+ {
+ double encVal; //encoder value
+
- fanLabel.Visible = false;
- fanLabel.ForeColor = Color.Blue;
- fanLabel.Text = "Fans On";
+ if (double.TryParse(txtCustEncoderVal.Text, out encVal))
+ {
+ _azEncoderDegrees -= encVal;
+ }
+ else
+ {
+ MessageBox.Show("Invalid entry in Encoder field", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
+ }
+
+ private void editDiagScriptsButton_Click(object sender, EventArgs e)
+ {
+ logger.Info(Utilities.GetTimeStamp() + ": Edit Scripts Button Clicked");
+ int caseSwitch = diagnosticScriptCombo.SelectedIndex;
+
+ // The current orientation is needed for most scripts
+ Entities.Orientation currOrientation = rtController.GetCurrentOrientation();
- /*** Temperature Logic End***/
- /*
- if (controlRoom.RTControllerManagementThreads[rtId].AppointmentToDisplay != null)
+ switch (caseSwitch)
{
- SetStartTimeText(controlRoom.RTControllerManagementThreads[rtId].AppointmentToDisplay.StartTime.ToLocalTime().ToString("hh:mm tt"));
- SetEndTimeText(controlRoom.RTControllerManagementThreads[rtId].AppointmentToDisplay.EndTime.ToLocalTime().ToString("hh:mm tt"));
- SetApptStatusText(controlRoom.RTControllerManagementThreads[rtId].AppointmentToDisplay.Status.ToString());
+ case 1: // Elevation Lower Limit Switch
+ rtController.MoveRadioTelescopeToOrientation(new Entities.Orientation(currOrientation.Azimuth, -14), MovementPriority.Manual);
+ break;
+ case 2: // Elevation Upper Limit Switch
+ rtController.MoveRadioTelescopeToOrientation(new Entities.Orientation(currOrientation.Azimuth, 92), MovementPriority.Manual);
+ break;
+ default:
+
+ //Script cannot be run
+ break;
}
- //*/
- GetHardwareStatuses();
- SetCurrentAzimuthAndElevation();
+ }
- dataGridView1.Update();
-
+ private void button7_Click(object sender, EventArgs e)
+ {
+ string filename = Directory.GetCurrentDirectory() + "\\" + "UIDoc.pdf";
+ if (File.Exists(filename))
+ System.Diagnostics.Process.Start(filename);
+ }
+
+ private void ElevationProximityOverideButton1_Click(object sender, EventArgs e)
+ {
+ if (!rtController.overrides.overrideElevatProx0)
+ {
+ ElivationLimitSwitch0.Text = "OVERRIDING";
+ ElivationLimitSwitch0.BackColor = System.Drawing.Color.Red;
+ rtController.setOverride("elevation proximity (1)", true);
+ }
+ else if (rtController.overrides.overrideElevatProx0)
+ {
+ ElivationLimitSwitch0.Text = "ENABLED";
+ ElivationLimitSwitch0.BackColor = System.Drawing.Color.LimeGreen;
+ rtController.setOverride("elevation proximity (1)", false);
+ }
}
- private void DiagnosticsForm_Load(object sender, System.EventArgs e)
+ private void ElevationProximityOverideButton2_Click(object sender, EventArgs e)
{
+ if (!rtController.overrides.overrideElevatProx90)
+ {
+ ElevationLimitSwitch90.Text = "OVERRIDING";
+ ElevationLimitSwitch90.BackColor = System.Drawing.Color.Red;
+ rtController.setOverride("elevation proximity (2)", true);
+ }
+ else
+ {
+ ElevationLimitSwitch90.Text = "ENABLED";
+ ElevationLimitSwitch90.BackColor = System.Drawing.Color.LimeGreen;
+ rtController.setOverride("elevation proximity (2)", false);
+ }
+ }
+ private void diagnosticScriptCombo_SelectedIndexChanged(object sender, EventArgs e)
+ {
+ if (diagnosticScriptCombo.SelectedIndex >= 0)
+ {
+ runDiagScriptsButton.Enabled = true;
+ runDiagScriptsButton.BackColor = System.Drawing.Color.LimeGreen;
+ }
}
- private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
+ private void celTempConvert_Click(object sender, EventArgs e)
{
+ if (fahrenheit == true)
+ {
+ fahrenheit = false;
+ celTempConvert.BackColor = System.Drawing.Color.LimeGreen;
+ farTempConvert.BackColor = System.Drawing.Color.DarkGray;
+ }
}
- private void btnTest_Click(object sender, System.EventArgs e)
+ private void farTempConvert_Click(object sender, EventArgs e)
{
- double temperature = 0;
+ if (fahrenheit == false)
+ {
+ fahrenheit = true;
+ celTempConvert.BackColor = System.Drawing.Color.DarkGray;
+ farTempConvert.BackColor = System.Drawing.Color.LimeGreen;
+
+ }
+ }
- if(double.TryParse(txtTemperature.Text, out temperature))
+ private void WSOverride_Click(object sender, EventArgs e)
+ {
+ if (!mainF.getWSOverride())
{
- fldAzTemp.Text = temperature.ToString();
+ WSOverride.Text = "OVERRIDING";
+ WSOverride.BackColor = System.Drawing.Color.Red;
+ mainF.setWSOverride(true);
+
+ // We are only calling this to send the push notification and email, it does not actually set the override
+ rtController.setOverride("weather station", true);
}
else
{
- MessageBox.Show("Invalid entry in Temperature field", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ WSOverride.Text = "ENABLED";
+ WSOverride.BackColor = System.Drawing.Color.LimeGreen;
+ mainF.setWSOverride(false);
+
+ // We are only calling this to send the push notification and email, it does not actually set the override
+ rtController.setOverride("weather station", false);
}
}
- private void btnAddOneTemp_Click(object sender, System.EventArgs e)
+ private void MGOverride_Click(object sender, EventArgs e)
{
- _elevationTemp += 1;
+ if (!rtController.overrides.overrideGate)
+ {
+ MGOverride.Text = "OVERRIDING";
+ MGOverride.BackColor = System.Drawing.Color.Red;
+ rtController.setOverride("main gate", true);
+ }
+ else if (rtController.overrides.overrideGate)
+ {
+ MGOverride.Text = "ENABLED";
+ MGOverride.BackColor = System.Drawing.Color.LimeGreen;
+ rtController.setOverride("main gate", false);
+ }
}
- private void btnAddFiveTemp_Click(object sender, System.EventArgs e)
+ private void AzMotTempSensOverride_Click(object sender, EventArgs e)
{
- _elevationTemp += 5;
+ if (!rtController.overrides.overrideAzimuthMotTemp)
+ {
+ AzMotTempSensOverride.Text = "OVERRIDING";
+ AzMotTempSensOverride.BackColor = System.Drawing.Color.Red;
+
+ rtController.setOverride("azimuth motor temperature", true);
+ }
+ else if (rtController.overrides.overrideAzimuthMotTemp)
+ {
+ AzMotTempSensOverride.Text = "ENABLED";
+ AzMotTempSensOverride.BackColor = System.Drawing.Color.LimeGreen;
+
+ rtController.setOverride("azimuth motor temperature", false);
+ }
+ }
+
+ private void ElMotTempSensOverride_Click(object sender, EventArgs e)
+ {
+ if (!rtController.overrides.overrideElevatMotTemp)
+ {
+ ElMotTempSensOverride.Text = "OVERRIDING";
+ ElMotTempSensOverride.BackColor = System.Drawing.Color.Red;
+
+ rtController.setOverride("elevation motor temperature", true);
+ }
+ else if (rtController.overrides.overrideElevatMotTemp)
+ {
+ ElMotTempSensOverride.Text = "ENABLED";
+ ElMotTempSensOverride.BackColor = System.Drawing.Color.LimeGreen;
+
+ rtController.setOverride("elevation motor temperature", false);
+ }
}
- private void button1_Click(object sender, System.EventArgs e)
+ private void buttonWS_Click(object sender, EventArgs e)
{
- _elevationTemp -= 1;
+ // create a override by the control room computer
+ controlRoom.RTControllerManagementThreads[0].ActiveOverrides.Add(new Override(SensorItemEnum.WIND, "Control Room Computer"));
+ controlRoom.RTControllerManagementThreads[0].checkCurrentSensorAndOverrideStatus();
+
}
- private void button2_Click(object sender, System.EventArgs e)
+ // Getter for RadioTelescopeController
+ public RadioTelescopeController getRTController()
{
- _elevationTemp -= 5;
+ return rtController;
+ }
+
+ ///
+ /// This runs through and checks if any sensor settings have changed. For example, someone might set an
+ /// override or change the sensor initialization from the mobile app, so we would want that change to
+ /// show up in the Diagnostics Form.
+ ///
+ ///
+ ///
+ private void SensorSettingsRoutine(object sender, DoWorkEventArgs e)
+ {
+ // Current overrides
+ bool currMain = rtController.overrides.overrideGate;
+ bool currWS = controlRoom.weatherStationOverride;
+ bool currAZ = rtController.overrides.overrideAzimuthMotTemp;
+ bool currEL = rtController.overrides.overrideElevatMotTemp;
+ bool currElProx0 = rtController.overrides.overrideElevatProx0;
+ bool currElProx90 = rtController.overrides.overrideElevatProx90;
+ bool currAzimuthAbsEncoder = rtController.overrides.overrideAzimuthAbsEncoder;
+ bool currElevationAbsEncoder = rtController.overrides.overrideElevationAbsEncoder;
+ bool currAzimuthAccelerometer = rtController.overrides.overrideAzimuthAccelerometer;
+ bool currElevationAccelerometer = rtController.overrides.overrideElevationAccelerometer;
+ bool currCounterbalanceAccelerometer = rtController.overrides.overrideCounterbalanceAccelerometer;
+
+ bool newMain, newWS, newAZ, newEL, newElProx0, newElProx90,
+ newAzimuthAbsEncoder, newElevationAbsEncoder, newAzimuthAccelerometer, newElevationAccelerometer, newCounterbalanceAccelerometer;
+
+ // Only keep running this loop while the Radio Telescope is online
+ while (rtController.RadioTelescope.online == 1)
+ {
+ newMain = rtController.overrides.overrideGate;
+ newWS = controlRoom.weatherStationOverride;
+ newAZ = rtController.overrides.overrideAzimuthMotTemp;
+ newEL = rtController.overrides.overrideElevatMotTemp;
+ newElProx0 = rtController.overrides.overrideElevatProx0;
+ newElProx90 = rtController.overrides.overrideElevatProx90;
+ newAzimuthAbsEncoder = rtController.overrides.overrideAzimuthAbsEncoder;
+ newElevationAbsEncoder = rtController.overrides.overrideElevationAbsEncoder;
+ newAzimuthAccelerometer = rtController.overrides.overrideAzimuthAccelerometer;
+ newElevationAccelerometer = rtController.overrides.overrideElevationAccelerometer;
+ newCounterbalanceAccelerometer = rtController.overrides.overrideCounterbalanceAccelerometer;
+
+ if (currWS != newWS ||
+ currMain != newMain ||
+ currAZ != newAZ ||
+ currEL != newEL ||
+ currElProx0 != newElProx0 ||
+ currElProx90 != newElProx90 ||
+ currAzimuthAbsEncoder != newAzimuthAbsEncoder ||
+ currElevationAbsEncoder != newElevationAbsEncoder ||
+ currAzimuthAccelerometer != newAzimuthAccelerometer ||
+ currElevationAccelerometer != newElevationAccelerometer ||
+ currCounterbalanceAccelerometer != newCounterbalanceAccelerometer)
+ {
+ currMain = newMain;
+ currWS = newWS;
+ currAZ = newAZ;
+ currEL = newEL;
+ currElProx0 = newElProx0;
+ currElProx90 = newElProx90;
+ currAzimuthAbsEncoder = newAzimuthAbsEncoder;
+ currElevationAbsEncoder = newElevationAbsEncoder;
+ currAzimuthAccelerometer = newAzimuthAccelerometer;
+ currElevationAccelerometer = newElevationAccelerometer;
+ currCounterbalanceAccelerometer = newCounterbalanceAccelerometer;
+
+ Utilities.WriteToGUIFromThread(this, () => {
+ UpdateOverrideButtons(currMain, currWS, currAZ, currEL, currElProx0, currElProx90,
+ currAzimuthAbsEncoder, currElevationAbsEncoder, currAzimuthAccelerometer, currElevationAccelerometer, currCounterbalanceAccelerometer);
+ });
+ }
+ Thread.Sleep(1000);
+ }
}
- private void btnAddXTemp_Click(object sender, System.EventArgs e)
+ // Loads the override buttons
+ public void UpdateOverrideButtons(bool currMain, bool currWS, bool currAZ, bool currEL, bool currElProx0, bool currElProx90,
+ bool azimuthAbsEncoder, bool elevationAbsEncoder, bool azimuthAccelerometer, bool elevationAccelerometer, bool counterbalanceAccelerometer)
{
- double tempVal; //temperature value
-
+ // Weather Station Override
+ if(currWS)
+ {
+ WSOverride.Text = "OVERRIDING";
+ WSOverride.BackColor = System.Drawing.Color.Red;
+ }
+ else
+ {
+ WSOverride.Text = "ENABLED";
+ WSOverride.BackColor = System.Drawing.Color.LimeGreen;
+ }
+
+ // Main Gate Override
+ if(currMain)
+ {
+ MGOverride.Text = "OVERRIDING";
+ MGOverride.BackColor = System.Drawing.Color.Red;
+ }
+ else
+ {
+ MGOverride.Text = "ENABLED";
+ MGOverride.BackColor = System.Drawing.Color.LimeGreen;
+ }
+
+ // Azimuth Motor Override
+ if(currAZ)
+ {
+ AzMotTempSensOverride.Text = "OVERRIDING";
+ AzMotTempSensOverride.BackColor = System.Drawing.Color.Red;
+ }
+ else
+ {
+ AzMotTempSensOverride.Text = "ENABLED";
+ AzMotTempSensOverride.BackColor = System.Drawing.Color.LimeGreen;
+ }
+
+ // Elevation Motor Override
+ if(currEL)
+ {
+ ElMotTempSensOverride.Text = "OVERRIDING";
+ ElMotTempSensOverride.BackColor = System.Drawing.Color.Red;
+ }
+ else
+ {
+ ElMotTempSensOverride.Text = "ENABLED";
+ ElMotTempSensOverride.BackColor = System.Drawing.Color.LimeGreen;
+ }
+
+ // Elevation Limit Switch 0 Degrees Override
+ if(currElProx0)
+ {
+ ElivationLimitSwitch0.Text = "OVERRIDING";
+ ElivationLimitSwitch0.BackColor = System.Drawing.Color.Red;
+ }
+ else
+ {
+ ElivationLimitSwitch0.Text = "ENABLED";
+ ElivationLimitSwitch0.BackColor = System.Drawing.Color.LimeGreen;
+ }
+
+ // Elevation Limit Switch 90 Degrees Override
+ if (currElProx90)
+ {
+ ElevationLimitSwitch90.Text = "OVERRIDING";
+ ElevationLimitSwitch90.BackColor = System.Drawing.Color.Red;
+ }
+ else
+ {
+ ElevationLimitSwitch90.Text = "ENABLED";
+ ElevationLimitSwitch90.BackColor = System.Drawing.Color.LimeGreen;
+ }
+
+ // Azimuth ABS Encoder Override
+ if (azimuthAbsEncoder)
+ {
+ btnAzimuthAbsoluteEncoder.Text = "OVERRIDING";
+ btnAzimuthAbsoluteEncoder.BackColor = System.Drawing.Color.Red;
+ }
+ else
+ {
+ btnAzimuthAbsoluteEncoder.Text = "ENABLED";
+ btnAzimuthAbsoluteEncoder.BackColor = System.Drawing.Color.LimeGreen;
+ }
+
+ // Elevation ABS Encoder Override
+ if (elevationAbsEncoder)
+ {
+ btnElevationAbsoluteEncoder.Text = "OVERRIDING";
+ btnElevationAbsoluteEncoder.BackColor = System.Drawing.Color.Red;
+ }
+ else
+ {
+ btnElevationAbsoluteEncoder.Text = "ENABLED";
+ btnElevationAbsoluteEncoder.BackColor = System.Drawing.Color.LimeGreen;
+ }
+
+ // Azimuth Accelerometer Override
+ if (azimuthAccelerometer)
+ {
+ btnAzimuthMotorAccelerometerOverride.Text = "OVERRIDING";
+ btnAzimuthMotorAccelerometerOverride.BackColor = System.Drawing.Color.Red;
+ }
+ else
+ {
+ btnAzimuthMotorAccelerometerOverride.Text = "ENABLED";
+ btnAzimuthMotorAccelerometerOverride.BackColor = System.Drawing.Color.LimeGreen;
+ }
+
+ // Elevation Accelerometer Override
+ if (elevationAccelerometer)
+ {
+ btnElevationMotorAccelerometerOverride.Text = "OVERRIDING";
+ btnElevationMotorAccelerometerOverride.BackColor = System.Drawing.Color.Red;
+ }
+ else
+ {
+ btnElevationMotorAccelerometerOverride.Text = "ENABLED";
+ btnElevationMotorAccelerometerOverride.BackColor = System.Drawing.Color.LimeGreen;
+ }
- if (double.TryParse(txtCustTemp.Text, out tempVal))
+ // Counterbalce Accelerometer Override
+ if (counterbalanceAccelerometer)
{
- _elevationTemp += tempVal;
+ btnCounterbalanceMotorAccelerometerOverride.Text = "OVERRIDING";
+ btnCounterbalanceMotorAccelerometerOverride.BackColor = System.Drawing.Color.Red;
}
else
{
- MessageBox.Show("Invalid entry in Temperature field", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ btnCounterbalanceMotorAccelerometerOverride.Text = "ENABLED";
+ btnCounterbalanceMotorAccelerometerOverride.BackColor = System.Drawing.Color.LimeGreen;
}
}
- private void button3_Click(object sender, System.EventArgs e)
+ private void btnResetMcuErrors_Click(object sender, EventArgs e)
{
- double tempVal; //temperature value
+ if(rtController.ResetMCUErrors())
+ {
+ logger.Info(Utilities.GetTimeStamp() + "Successfully reset motor controller errors.");
+ }
+ else
+ {
+ logger.Info(Utilities.GetTimeStamp() + "Cannot reset motor controller errors while another command is running. Please wait until the other command has completed.");
+ }
+ }
+ private void btnAzimuthAbsoluteEncoder_Click(object sender, EventArgs e)
+ {
+ if (!rtController.overrides.overrideAzimuthAbsEncoder)
+ {
+ btnAzimuthAbsoluteEncoder.Text = "OVERRIDING";
+ btnAzimuthAbsoluteEncoder.BackColor = System.Drawing.Color.Red;
- if (double.TryParse(txtCustTemp.Text, out tempVal))
+ rtController.setOverride("azimuth absolute encoder", true);
+ }
+ else if (rtController.overrides.overrideAzimuthAbsEncoder)
{
- _elevationTemp -= tempVal;
+ btnAzimuthAbsoluteEncoder.Text = "ENABLED";
+ btnAzimuthAbsoluteEncoder.BackColor = System.Drawing.Color.LimeGreen;
+
+ rtController.setOverride("azimuth absolute encoder", false);
}
- else
+ }
+
+ private void btnElevationAbsoluteEncoder_Click(object sender, EventArgs e)
+ {
+ if (!rtController.overrides.overrideElevationAbsEncoder)
+ {
+ btnElevationAbsoluteEncoder.Text = "OVERRIDING";
+ btnElevationAbsoluteEncoder.BackColor = System.Drawing.Color.Red;
+
+ rtController.setOverride("elevation absolute encoder", true);
+ }
+ else if (rtController.overrides.overrideElevationAbsEncoder)
+ {
+ btnElevationAbsoluteEncoder.Text = "ENABLED";
+ btnElevationAbsoluteEncoder.BackColor = System.Drawing.Color.LimeGreen;
+
+ rtController.setOverride("elevation absolute encoder", false);
+ }
+ }
+
+ private void btnAzimuthMotorAccelerometerOverride_Click(object sender, EventArgs e)
+ {
+ if (!rtController.overrides.overrideAzimuthAccelerometer)
+ {
+ btnAzimuthMotorAccelerometerOverride.Text = "OVERRIDING";
+ btnAzimuthMotorAccelerometerOverride.BackColor = System.Drawing.Color.Red;
+
+ rtController.setOverride("azimuth motor accelerometer", true);
+ }
+ else if (rtController.overrides.overrideAzimuthAccelerometer)
{
- MessageBox.Show("Invalid entry in Temperature field", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ btnAzimuthMotorAccelerometerOverride.Text = "ENABLED";
+ btnAzimuthMotorAccelerometerOverride.BackColor = System.Drawing.Color.LimeGreen;
+
+ rtController.setOverride("azimuth motor accelerometer", false);
}
}
- private void timer2_Tick(object sender, System.EventArgs e)
+ private void btnElevationMotorAccelerometerOverride_Click(object sender, EventArgs e)
{
+ if (!rtController.overrides.overrideElevationAccelerometer)
+ {
+ btnElevationMotorAccelerometerOverride.Text = "OVERRIDING";
+ btnElevationMotorAccelerometerOverride.BackColor = System.Drawing.Color.Red;
+ rtController.setOverride("elevation motor accelerometer", true);
+ }
+ else if (rtController.overrides.overrideElevationAccelerometer)
+ {
+ btnElevationMotorAccelerometerOverride.Text = "ENABLED";
+ btnElevationMotorAccelerometerOverride.BackColor = System.Drawing.Color.LimeGreen;
+
+ rtController.setOverride("elevation motor accelerometer", false);
+ }
}
- private void lblAzLimStatus2_Click(object sender, System.EventArgs e)
+ private void btnCounterbalanceMotorAccelerometerOverride_Click(object sender, EventArgs e)
{
+ if (!rtController.overrides.overrideCounterbalanceAccelerometer)
+ {
+ btnCounterbalanceMotorAccelerometerOverride.Text = "OVERRIDING";
+ btnCounterbalanceMotorAccelerometerOverride.BackColor = System.Drawing.Color.Red;
+ rtController.setOverride("counterbalance accelerometer", true);
+ }
+ else if (rtController.overrides.overrideCounterbalanceAccelerometer)
+ {
+ btnCounterbalanceMotorAccelerometerOverride.Text = "ENABLED";
+ btnCounterbalanceMotorAccelerometerOverride.BackColor = System.Drawing.Color.LimeGreen;
+
+ rtController.setOverride("counterbalance accelerometer", false);
+ }
}
- private void button4_Click(object sender, System.EventArgs e)
+ private async void UpdateSensorInitiliazation_Click(object sender, EventArgs e)
{
- _azEncoderDegrees += 1;
+ // This must be executed async so the status updates/timer keeps ticking
+ await Task.Run(() => {
+ // First set all the checkboxes equal to the sensor network config
+ SensorNetworkConfig.AzimuthTemp1Init = AzimuthTemperature1.Checked;
+ SensorNetworkConfig.ElevationTemp1Init = ElevationTemperature1.Checked;
+ SensorNetworkConfig.AzimuthAccelerometerInit = AzimuthAccelerometer.Checked;
+ SensorNetworkConfig.ElevationAccelerometerInit = ElevationAccelerometer.Checked;
+ SensorNetworkConfig.CounterbalanceAccelerometerInit = CounterbalanceAccelerometer.Checked;
+ SensorNetworkConfig.ElevationEncoderInit = ElevationEncoder.Checked;
+ SensorNetworkConfig.AzimuthEncoderInit = AzimuthEncoder.Checked;
+
+ // Update initializations
+ SensorNetworkConfig.TimeoutDataRetrieval = (int)(double.Parse(txtDataTimeout.Text) * 1000);
+ SensorNetworkConfig.TimeoutInitialization = (int)(double.Parse(txtInitTimeout.Text) * 1000);
+
+ // Update the config in the DB
+ DatabaseOperations.UpdateSensorNetworkConfig(SensorNetworkConfig);
+ // reboot
+ rtController.RadioTelescope.SensorNetworkServer.RebootSensorNetwork();
+ });
}
- private void button5_Click(object sender, System.EventArgs e)
+ private void txtDataTimeout_TextChanged(object sender, EventArgs e)
{
- _azEncoderDegrees += 5;
+ DataTimeoutValid = false;
+
+ if(Validator.IsDouble(txtDataTimeout.Text))
+ {
+ DataTimeoutValid = Validator.IsBetween(double.Parse(txtDataTimeout.Text), 0, null);
+ }
+
+ if(DataTimeoutValid)
+ {
+ txtDataTimeout.BackColor = Color.White;
+ DataTimeoutValidation.Hide(lblDataTimeout);
+
+ // If the other tooltip is not in error, the button may be clicked
+ if (InitTimeoutValid) UpdateSensorInitiliazation.Enabled = true;
+ }
+ else
+ {
+ txtDataTimeout.BackColor = Color.Yellow;
+ DataTimeoutValidation.Show("Must be a positive double value.", lblDataTimeout, 2000);
+ UpdateSensorInitiliazation.Enabled = false;
+ }
}
- private void btnSubtractOneEncoder_Click(object sender, System.EventArgs e)
+ private void txtInitTimeout_TextChanged(object sender, EventArgs e)
{
- _azEncoderDegrees -= 1;
-
+ InitTimeoutValid = false;
+
+ if (Validator.IsDouble(txtInitTimeout.Text))
+ {
+ InitTimeoutValid = Validator.IsBetween(double.Parse(txtInitTimeout.Text), 0, null);
+ }
+
+ if (InitTimeoutValid)
+ {
+ txtInitTimeout.BackColor = Color.White;
+ InitTimeoutValidation.Hide(lblInitTimeout);
+
+ // If the other tooltip is not in error, the button may be clicked
+ if (DataTimeoutValid) UpdateSensorInitiliazation.Enabled = true;
+ }
+ else
+ {
+ txtInitTimeout.BackColor = Color.Yellow;
+ InitTimeoutValidation.Show("Must be a positive double value.", lblInitTimeout, 2000);
+ UpdateSensorInitiliazation.Enabled = false;
+ }
}
- private void btnSubtractFiveEncoder_Click(object sender, System.EventArgs e)
+ private void UpdateSWStopsButton_Click(object sender, EventArgs e)
{
- _azEncoderDegrees -= 5;
+
+ if(ValidLowerSWStopLimit && ValidUpperSWStopLimit)
+ {
+ rtController.RadioTelescope.maxElevationDegrees = double.Parse(UpperSWStopsLimitText.Text);
+ rtController.RadioTelescope.minElevationDegrees = double.Parse(LowerSWStopsLimitText.Text);
+
+ logger.Info(Utilities.GetTimeStamp() + String.Format(" Updating Software stop thresholds... New values: Lower = {0} , Upper = {1} ", double.Parse(LowerSWStopsLimitText.Text), double.Parse(UpperSWStopsLimitText.Text)));
+ DatabaseOperations.UpdateTelescope(rtController.RadioTelescope);
+ }
+
}
- private void btnAddXEncoder_Click(object sender, System.EventArgs e)
+ private void ValidateUpperLimit()
{
- double encVal; //encoder value
+ ValidUpperSWStopLimit = false;
+ bool isNumeric = Double.TryParse(UpperSWStopsLimitText.Text, out double requestedUpperLimit);
- if (double.TryParse(txtCustEncoderVal.Text, out encVal))
+ if (isNumeric)
{
- _azEncoderDegrees += encVal;
+ Double.TryParse(LowerSWStopsLimitText.Text, out double requestedLowerLimit);
+
+ double RequestedUpperLimit = double.Parse(UpperSWStopsLimitText.Text);
+
+ if (!ValidUpperSWStopLimit)
+ {
+ requestedLowerLimit = MiscellaneousConstants.MIN_SOFTWARE_STOP_EL_DEGREES;
+ }
+
+ if (!Validator.IsBetween(RequestedUpperLimit, requestedLowerLimit, MiscellaneousConstants.MAX_SOFTWARE_STOP_EL_DEGREES))
+ {
+
+ UpperLimitToolTip.Show(String.Format("Upper Software Stop limit must be between {0} and {1} degrees (inclusive)", requestedLowerLimit, MiscellaneousConstants.MAX_SOFTWARE_STOP_EL_DEGREES), UpperSWStopsLimitText);
+ UpperSWStopsLimitText.BackColor = Color.Yellow;
+ ValidUpperSWStopLimit = false;
+ }
+ else
+ {
+ UpperLimitToolTip.Hide(UpperSWStopsLimitText);
+ UpperSWStopsLimitText.BackColor = Color.White;
+ ValidUpperSWStopLimit = true;
+ }
}
else
{
- MessageBox.Show("Invalid entry in Encoder field", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ UpperLimitToolTip.Show("Upper Software Stop limit must be a number", UpperSWStopsLimitText);
+ UpperSWStopsLimitText.BackColor = Color.Yellow;
+ ValidUpperSWStopLimit = false;
}
}
- private void btnSubtractXEncoder_Click(object sender, System.EventArgs e)
+ private void ValidateLowerLimit()
{
- double encVal; //encoder value
+ ValidLowerSWStopLimit = false;
+ bool isNumeric = Double.TryParse(LowerSWStopsLimitText.Text, out double requestedLowerLimit);
- if (double.TryParse(txtCustEncoderVal.Text, out encVal))
+ if (isNumeric)
{
- _azEncoderDegrees -= encVal;
+ Double.TryParse(UpperSWStopsLimitText.Text, out double requestedUpperLimit);
+
+ if (!ValidUpperSWStopLimit)
+ {
+ requestedUpperLimit = MiscellaneousConstants.MAX_SOFTWARE_STOP_EL_DEGREES;
+ }
+
+ if (!Validator.IsBetween(requestedLowerLimit, MiscellaneousConstants.MIN_SOFTWARE_STOP_EL_DEGREES, requestedUpperLimit))
+ {
+ LowerLimitToolTip.Show(String.Format("Lower Software Stop limit must be between {0} and {1} degrees (inclusive)", MiscellaneousConstants.MIN_SOFTWARE_STOP_EL_DEGREES, requestedUpperLimit), LowerSWStopsLimitText);
+ LowerSWStopsLimitText.BackColor = Color.Yellow;
+ ValidLowerSWStopLimit = false;
+
+ }
+ else
+ {
+ LowerLimitToolTip.Hide(LowerSWStopsLimitText);
+ LowerSWStopsLimitText.BackColor = Color.White;
+ ValidLowerSWStopLimit = true;
+ }
}
else
{
- MessageBox.Show("Invalid entry in Encoder field", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ LowerLimitToolTip.Show("Lower Software Stop limit must be a number", LowerSWStopsLimitText);
+ LowerSWStopsLimitText.BackColor = Color.Yellow;
+ ValidLowerSWStopLimit = false;
}
+
+ }
+
+ private void UpperSWStopsLimitText_TextChanged(object sender, EventArgs e)
+ {
+ ValidateUpperLimit();
+ ValidateLowerLimit();
}
+
+ private void LowerSWStopsLimitText_TextChanged(object sender, EventArgs e)
+ {
+ ValidateUpperLimit();
+ ValidateLowerLimit();
+
+ }
+
}
}
diff --git a/ControlRoomApplication/ControlRoomApplication/GUI/DiagnosticsForm.resx b/ControlRoomApplication/ControlRoomApplication/GUI/DiagnosticsForm.resx
index 1f666f26..92518831 100644
--- a/ControlRoomApplication/ControlRoomApplication/GUI/DiagnosticsForm.resx
+++ b/ControlRoomApplication/ControlRoomApplication/GUI/DiagnosticsForm.resx
@@ -120,4 +120,19 @@
17, 17
+
+ 104, 17
+
+
+ 281, 17
+
+
+ 450, 17
+
+
+ 603, 17
+
+
+ 53
+
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/GUI/DropDownEnums/PLCDropdown.cs b/ControlRoomApplication/ControlRoomApplication/GUI/DropDownEnums/PLCDropdown.cs
new file mode 100644
index 00000000..77334229
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/GUI/DropDownEnums/PLCDropdown.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ControlRoomApplication.GUI.DropDownEnums
+{
+ public enum PLCDropdown
+ {
+ ProductionPLC,
+ ScalePLC,
+ SimulatedPLC,
+ TestPLC
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/GUI/DropDownEnums/SensorNetworkDropdown.cs b/ControlRoomApplication/ControlRoomApplication/GUI/DropDownEnums/SensorNetworkDropdown.cs
new file mode 100644
index 00000000..a38ad8ef
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/GUI/DropDownEnums/SensorNetworkDropdown.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ControlRoomApplication.GUI.DropDownEnums
+{
+ ///
+ /// This will contain every option of the Sensor Network combo box so we can more easily tell what each thing is
+ ///
+ public enum SensorNetworkDropdown
+ {
+ ///
+ /// This gets selected if we are connecting to the production sensor network, or another simulation that is
+ /// not running within the control room.
+ ///
+ ProductionSensorNetwork,
+
+ ///
+ /// This gets selected if we are running the simulated sensor network within the control room.
+ ///
+ SimulatedSensorNetwork
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/GUI/DropDownEnums/SpectraCyberDropdown.cs b/ControlRoomApplication/ControlRoomApplication/GUI/DropDownEnums/SpectraCyberDropdown.cs
new file mode 100644
index 00000000..9156f1ff
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/GUI/DropDownEnums/SpectraCyberDropdown.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ControlRoomApplication.GUI.DropDownEnums
+{
+ public enum SpectraCyberDropdown
+ {
+ ProductionSpectraCyber,
+ SimulatedSpectraCyber
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/GUI/DropDownEnums/WeatherStationDropdown.cs b/ControlRoomApplication/ControlRoomApplication/GUI/DropDownEnums/WeatherStationDropdown.cs
new file mode 100644
index 00000000..581db6ad
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/GUI/DropDownEnums/WeatherStationDropdown.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ControlRoomApplication.GUI.DropDownEnums
+{
+ public enum WeatherStationDropdown
+ {
+ ProductionWeatherStation,
+ SimulatedWeatherStation
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/GUI/EditDiagScriptsForm.Designer.cs b/ControlRoomApplication/ControlRoomApplication/GUI/EditDiagScriptsForm.Designer.cs
new file mode 100644
index 00000000..6746a9a8
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/GUI/EditDiagScriptsForm.Designer.cs
@@ -0,0 +1,186 @@
+namespace ControlRoomApplication.GUI
+{
+ partial class EditDiagScriptsForm
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.button4 = new System.Windows.Forms.Button();
+ this.splitContainer1 = new System.Windows.Forms.SplitContainer();
+ this.comboBox1 = new System.Windows.Forms.ComboBox();
+ this.label2 = new System.Windows.Forms.Label();
+ this.button2 = new System.Windows.Forms.Button();
+ this.textBox1 = new System.Windows.Forms.TextBox();
+ this.button3 = new System.Windows.Forms.Button();
+ this.button1 = new System.Windows.Forms.Button();
+ ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();
+ this.splitContainer1.Panel1.SuspendLayout();
+ this.splitContainer1.Panel2.SuspendLayout();
+ this.splitContainer1.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // button4
+ //
+ this.button4.BackColor = System.Drawing.Color.LimeGreen;
+ this.button4.Cursor = System.Windows.Forms.Cursors.Hand;
+ this.button4.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+ this.button4.Location = new System.Drawing.Point(203, 196);
+ this.button4.Name = "button4";
+ this.button4.Size = new System.Drawing.Size(129, 23);
+ this.button4.TabIndex = 11;
+ this.button4.Text = "Apply Changes";
+ this.button4.UseVisualStyleBackColor = false;
+ //
+ // splitContainer1
+ //
+ this.splitContainer1.BackColor = System.Drawing.Color.Gainsboro;
+ this.splitContainer1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
+ this.splitContainer1.Location = new System.Drawing.Point(1, 3);
+ this.splitContainer1.Name = "splitContainer1";
+ this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal;
+ //
+ // splitContainer1.Panel1
+ //
+ this.splitContainer1.Panel1.BackColor = System.Drawing.Color.DarkGray;
+ this.splitContainer1.Panel1.Controls.Add(this.comboBox1);
+ this.splitContainer1.Panel1.Controls.Add(this.label2);
+ this.splitContainer1.Panel1.Controls.Add(this.button2);
+ this.splitContainer1.Panel1.Paint += new System.Windows.Forms.PaintEventHandler(this.splitContainer1_Panel1_Paint);
+ //
+ // splitContainer1.Panel2
+ //
+ this.splitContainer1.Panel2.BackColor = System.Drawing.Color.DarkGray;
+ this.splitContainer1.Panel2.Controls.Add(this.textBox1);
+ this.splitContainer1.Panel2.Controls.Add(this.button3);
+ this.splitContainer1.Panel2.Controls.Add(this.button1);
+ this.splitContainer1.Panel2.Paint += new System.Windows.Forms.PaintEventHandler(this.splitContainer1_Panel2_Paint);
+ this.splitContainer1.Size = new System.Drawing.Size(331, 187);
+ this.splitContainer1.SplitterDistance = 74;
+ this.splitContainer1.TabIndex = 10;
+ //
+ // comboBox1
+ //
+ this.comboBox1.FormattingEnabled = true;
+ this.comboBox1.Items.AddRange(new object[] {
+ "Snow Dump",
+ "Stow telescope",
+ "Full 360 Clockwise",
+ "Full 360 Counter-Clockwise",
+ "Calibrate Telescope"});
+ this.comboBox1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.comboBox1.Location = new System.Drawing.Point(11, 29);
+ this.comboBox1.Name = "comboBox1";
+ this.comboBox1.Size = new System.Drawing.Size(160, 21);
+ this.comboBox1.TabIndex = 1;
+ this.comboBox1.SelectedIndexChanged += new System.EventHandler(this.comboBox1_SelectedIndexChanged);
+ //
+ // label2
+ //
+ this.label2.AutoSize = true;
+ this.label2.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.label2.Location = new System.Drawing.Point(19, 10);
+ this.label2.Name = "label2";
+ this.label2.Size = new System.Drawing.Size(94, 16);
+ this.label2.TabIndex = 0;
+ this.label2.Text = "Current Scripts";
+ //
+ // button2
+ //
+ this.button2.BackColor = System.Drawing.Color.Silver;
+ this.button2.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+ this.button2.Location = new System.Drawing.Point(219, 29);
+ this.button2.Name = "button2";
+ this.button2.Size = new System.Drawing.Size(98, 23);
+ this.button2.TabIndex = 4;
+ this.button2.Text = "Remove Script";
+ this.button2.UseVisualStyleBackColor = false;
+ //
+ // textBox1
+ //
+ this.textBox1.Location = new System.Drawing.Point(11, 22);
+ this.textBox1.MaximumSize = new System.Drawing.Size(1000, 1000);
+ this.textBox1.Name = "textBox1";
+ this.textBox1.Size = new System.Drawing.Size(252, 20);
+ this.textBox1.TabIndex = 2;
+ this.textBox1.Text = "C:\\Users\\RadioTelescope\\DiagnosticScripts";
+ this.textBox1.TextChanged += new System.EventHandler(this.textBox1_TextChanged);
+ //
+ // button3
+ //
+ this.button3.BackColor = System.Drawing.Color.Silver;
+ this.button3.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+ this.button3.Location = new System.Drawing.Point(219, 67);
+ this.button3.MaximumSize = new System.Drawing.Size(1000, 1000);
+ this.button3.Name = "button3";
+ this.button3.Size = new System.Drawing.Size(98, 23);
+ this.button3.TabIndex = 5;
+ this.button3.Text = "Add Script";
+ this.button3.UseVisualStyleBackColor = false;
+ //
+ // button1
+ //
+ this.button1.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+ this.button1.Location = new System.Drawing.Point(292, 22);
+ this.button1.MaximumSize = new System.Drawing.Size(1000, 1000);
+ this.button1.Name = "button1";
+ this.button1.Size = new System.Drawing.Size(25, 25);
+ this.button1.TabIndex = 3;
+ this.button1.Text = "...";
+ this.button1.UseVisualStyleBackColor = true;
+ //
+ // EditDiagScriptsForm
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.BackColor = System.Drawing.Color.Gray;
+ this.ClientSize = new System.Drawing.Size(339, 227);
+ this.Controls.Add(this.button4);
+ this.Controls.Add(this.splitContainer1);
+ this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
+ this.Name = "EditDiagScriptsForm";
+ this.Text = "Edit Diagnostics Scripts";
+ this.splitContainer1.Panel1.ResumeLayout(false);
+ this.splitContainer1.Panel1.PerformLayout();
+ this.splitContainer1.Panel2.ResumeLayout(false);
+ this.splitContainer1.Panel2.PerformLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit();
+ this.splitContainer1.ResumeLayout(false);
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Button button4;
+ private System.Windows.Forms.SplitContainer splitContainer1;
+ private System.Windows.Forms.ComboBox comboBox1;
+ private System.Windows.Forms.Label label2;
+ private System.Windows.Forms.Button button2;
+ private System.Windows.Forms.TextBox textBox1;
+ private System.Windows.Forms.Button button3;
+ private System.Windows.Forms.Button button1;
+ }
+}
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/GUI/EditDiagScriptsForm.cs b/ControlRoomApplication/ControlRoomApplication/GUI/EditDiagScriptsForm.cs
new file mode 100644
index 00000000..dba4ad89
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/GUI/EditDiagScriptsForm.cs
@@ -0,0 +1,40 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace ControlRoomApplication.GUI
+{
+ public partial class EditDiagScriptsForm : Form
+ {
+ public EditDiagScriptsForm()
+ {
+ InitializeComponent();
+ }
+
+ private void splitContainer1_Panel1_Paint(object sender, PaintEventArgs e)
+ {
+
+ }
+
+ private void splitContainer1_Panel2_Paint(object sender, PaintEventArgs e)
+ {
+
+ }
+
+ private void textBox1_TextChanged(object sender, EventArgs e)
+ {
+
+ }
+
+ private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
+ {
+
+ }
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/GUI/ManualControlForm.resx b/ControlRoomApplication/ControlRoomApplication/GUI/EditDiagScriptsForm.resx
similarity index 93%
rename from ControlRoomApplication/ControlRoomApplication/GUI/ManualControlForm.resx
rename to ControlRoomApplication/ControlRoomApplication/GUI/EditDiagScriptsForm.resx
index caea00d2..1af7de15 100644
--- a/ControlRoomApplication/ControlRoomApplication/GUI/ManualControlForm.resx
+++ b/ControlRoomApplication/ControlRoomApplication/GUI/EditDiagScriptsForm.resx
@@ -117,10 +117,4 @@
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
- True
-
-
- 17, 17
-
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/GUI/EditTestForm.Designer.cs b/ControlRoomApplication/ControlRoomApplication/GUI/EditTestForm.Designer.cs
new file mode 100644
index 00000000..7011489a
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/GUI/EditTestForm.Designer.cs
@@ -0,0 +1,186 @@
+namespace ControlRoomApplication.GUI
+{
+ partial class editTestForm
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.button4 = new System.Windows.Forms.Button();
+ this.splitContainer1 = new System.Windows.Forms.SplitContainer();
+ this.comboBox1 = new System.Windows.Forms.ComboBox();
+ this.label2 = new System.Windows.Forms.Label();
+ this.button2 = new System.Windows.Forms.Button();
+ this.textBox1 = new System.Windows.Forms.TextBox();
+ this.button3 = new System.Windows.Forms.Button();
+ this.button1 = new System.Windows.Forms.Button();
+ ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();
+ this.splitContainer1.Panel1.SuspendLayout();
+ this.splitContainer1.Panel2.SuspendLayout();
+ this.splitContainer1.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // button4
+ //
+ this.button4.BackColor = System.Drawing.Color.LimeGreen;
+ this.button4.Cursor = System.Windows.Forms.Cursors.Hand;
+ this.button4.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+ this.button4.Location = new System.Drawing.Point(209, 204);
+ this.button4.Name = "button4";
+ this.button4.Size = new System.Drawing.Size(129, 23);
+ this.button4.TabIndex = 9;
+ this.button4.Text = "Apply Changes";
+ this.button4.UseVisualStyleBackColor = false;
+ //
+ // splitContainer1
+ //
+ this.splitContainer1.BackColor = System.Drawing.Color.Gainsboro;
+ this.splitContainer1.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
+ this.splitContainer1.Location = new System.Drawing.Point(12, 12);
+ this.splitContainer1.Name = "splitContainer1";
+ this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal;
+ //
+ // splitContainer1.Panel1
+ //
+ this.splitContainer1.Panel1.BackColor = System.Drawing.Color.DarkGray;
+ this.splitContainer1.Panel1.Controls.Add(this.comboBox1);
+ this.splitContainer1.Panel1.Controls.Add(this.label2);
+ this.splitContainer1.Panel1.Controls.Add(this.button2);
+ this.splitContainer1.Panel1.Paint += new System.Windows.Forms.PaintEventHandler(this.splitContainer1_Panel1_Paint);
+ //
+ // splitContainer1.Panel2
+ //
+ this.splitContainer1.Panel2.BackColor = System.Drawing.Color.DarkGray;
+ this.splitContainer1.Panel2.Controls.Add(this.textBox1);
+ this.splitContainer1.Panel2.Controls.Add(this.button3);
+ this.splitContainer1.Panel2.Controls.Add(this.button1);
+ this.splitContainer1.Panel2.Paint += new System.Windows.Forms.PaintEventHandler(this.splitContainer1_Panel2_Paint);
+ this.splitContainer1.Size = new System.Drawing.Size(331, 187);
+ this.splitContainer1.SplitterDistance = 74;
+ this.splitContainer1.TabIndex = 8;
+ //
+ // comboBox1
+ //
+ this.comboBox1.FormattingEnabled = true;
+ this.comboBox1.Items.AddRange(new object[] {
+ "Snow Dump",
+ "Stow telescope",
+ "Full 360 Clockwise",
+ "Full 360 Counter-Clockwise",
+ "Calibrate Telescope"});
+ this.comboBox1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.comboBox1.Location = new System.Drawing.Point(11, 29);
+ this.comboBox1.Name = "comboBox1";
+ this.comboBox1.Size = new System.Drawing.Size(160, 21);
+ this.comboBox1.TabIndex = 1;
+ this.comboBox1.SelectedIndexChanged += new System.EventHandler(this.comboBox1_SelectedIndexChanged);
+ //
+ // label2
+ //
+ this.label2.AutoSize = true;
+ this.label2.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.label2.Location = new System.Drawing.Point(19, 10);
+ this.label2.Name = "label2";
+ this.label2.Size = new System.Drawing.Size(94, 16);
+ this.label2.TabIndex = 0;
+ this.label2.Text = "Current Scripts";
+ //
+ // button2
+ //
+ this.button2.BackColor = System.Drawing.Color.Silver;
+ this.button2.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+ this.button2.Location = new System.Drawing.Point(219, 29);
+ this.button2.Name = "button2";
+ this.button2.Size = new System.Drawing.Size(98, 23);
+ this.button2.TabIndex = 4;
+ this.button2.Text = "Remove Script";
+ this.button2.UseVisualStyleBackColor = false;
+ //
+ // textBox1
+ //
+ this.textBox1.Location = new System.Drawing.Point(11, 22);
+ this.textBox1.MaximumSize = new System.Drawing.Size(1000, 1000);
+ this.textBox1.Name = "textBox1";
+ this.textBox1.Size = new System.Drawing.Size(252, 20);
+ this.textBox1.TabIndex = 2;
+ this.textBox1.Text = "C:\\Users\\RadioTelescope\\Scripts";
+ //
+ // button3
+ //
+ this.button3.BackColor = System.Drawing.Color.Silver;
+ this.button3.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+ this.button3.Location = new System.Drawing.Point(219, 67);
+ this.button3.MaximumSize = new System.Drawing.Size(1000, 1000);
+ this.button3.Name = "button3";
+ this.button3.Size = new System.Drawing.Size(98, 23);
+ this.button3.TabIndex = 5;
+ this.button3.Text = "Add Script";
+ this.button3.UseVisualStyleBackColor = false;
+ //
+ // button1
+ //
+ this.button1.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+ this.button1.Location = new System.Drawing.Point(292, 22);
+ this.button1.MaximumSize = new System.Drawing.Size(1000, 1000);
+ this.button1.Name = "button1";
+ this.button1.Size = new System.Drawing.Size(25, 25);
+ this.button1.TabIndex = 3;
+ this.button1.Text = "...";
+ this.button1.UseVisualStyleBackColor = true;
+ //
+ // editTestForm
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.BackColor = System.Drawing.SystemColors.ControlDarkDark;
+ this.ClientSize = new System.Drawing.Size(356, 245);
+ this.Controls.Add(this.button4);
+ this.Controls.Add(this.splitContainer1);
+ this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
+ this.Name = "editTestForm";
+ this.Text = "Edit Scripts";
+ this.Load += new System.EventHandler(this.Form1_Load);
+ this.splitContainer1.Panel1.ResumeLayout(false);
+ this.splitContainer1.Panel1.PerformLayout();
+ this.splitContainer1.Panel2.ResumeLayout(false);
+ this.splitContainer1.Panel2.PerformLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit();
+ this.splitContainer1.ResumeLayout(false);
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Button button4;
+ private System.Windows.Forms.SplitContainer splitContainer1;
+ private System.Windows.Forms.ComboBox comboBox1;
+ private System.Windows.Forms.Label label2;
+ private System.Windows.Forms.Button button2;
+ private System.Windows.Forms.TextBox textBox1;
+ private System.Windows.Forms.Button button3;
+ private System.Windows.Forms.Button button1;
+ }
+}
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/GUI/EditTestForm.cs b/ControlRoomApplication/ControlRoomApplication/GUI/EditTestForm.cs
new file mode 100644
index 00000000..69802166
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/GUI/EditTestForm.cs
@@ -0,0 +1,40 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace ControlRoomApplication.GUI
+{
+ public partial class editTestForm : Form
+ {
+ public editTestForm()
+ {
+ InitializeComponent();
+ }
+
+ private void Form1_Load(object sender, EventArgs e)
+ {
+
+ }
+
+ private void splitContainer1_Panel1_Paint(object sender, PaintEventArgs e)
+ {
+
+ }
+
+ private void splitContainer1_Panel2_Paint(object sender, PaintEventArgs e)
+ {
+
+ }
+
+ private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
+ {
+
+ }
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/GUI/EditTestForm.resx b/ControlRoomApplication/ControlRoomApplication/GUI/EditTestForm.resx
new file mode 100644
index 00000000..1af7de15
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/GUI/EditTestForm.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/GUI/FreeControlForm.Designer.cs b/ControlRoomApplication/ControlRoomApplication/GUI/FreeControlForm.Designer.cs
deleted file mode 100644
index 80fa665b..00000000
--- a/ControlRoomApplication/ControlRoomApplication/GUI/FreeControlForm.Designer.cs
+++ /dev/null
@@ -1,383 +0,0 @@
-namespace ControlRoomApplication.Main
-{
- partial class FreeControlForm
- {
- ///
- /// Required designer variable.
- ///
- private System.ComponentModel.IContainer components = null;
-
- ///
- /// Clean up any resources being used.
- ///
- /// true if managed resources should be disposed; otherwise, false.
- protected override void Dispose(bool disposing)
- {
- if (disposing && (components != null))
- {
- components.Dispose();
- }
- base.Dispose(disposing);
- }
-
- #region Windows Form Designer generated code
-
- ///
- /// Required method for Designer support - do not modify
- /// the contents of this method with the code editor.
- ///
- private void InitializeComponent()
- {
- this.components = new System.ComponentModel.Container();
- this.PosDecButton = new System.Windows.Forms.Button();
- this.NegDecButton = new System.Windows.Forms.Button();
- this.NegRAButton = new System.Windows.Forms.Button();
- this.PosRAButton = new System.Windows.Forms.Button();
- this.CalibrateButton = new System.Windows.Forms.Button();
- this.ActualRATextBox = new System.Windows.Forms.TextBox();
- this.ActualDecTextBox = new System.Windows.Forms.TextBox();
- this.ActualPositionLabel = new System.Windows.Forms.Label();
- this.ActualRALabel = new System.Windows.Forms.Label();
- this.ActualDecLabel = new System.Windows.Forms.Label();
- this.TargetDecLabel = new System.Windows.Forms.Label();
- this.TargetRALabel = new System.Windows.Forms.Label();
- this.TargetPositionLabel = new System.Windows.Forms.Label();
- this.TargetDecTextBox = new System.Windows.Forms.TextBox();
- this.TargetRATextBox = new System.Windows.Forms.TextBox();
- this.Title = new System.Windows.Forms.Label();
- this.timer1 = new System.Windows.Forms.Timer(this.components);
- this.IncrementButtons = new System.Windows.Forms.GroupBox();
- this.tenButton = new System.Windows.Forms.Button();
- this.fiveButton = new System.Windows.Forms.Button();
- this.oneButton = new System.Windows.Forms.Button();
- this.oneForthButton = new System.Windows.Forms.Button();
- this.editButton = new System.Windows.Forms.Button();
- this.errorLabel = new System.Windows.Forms.Label();
- this.IncrementButtons.SuspendLayout();
- this.SuspendLayout();
- //
- // PosDecButton
- //
- this.PosDecButton.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
- this.PosDecButton.BackColor = System.Drawing.Color.LightGray;
- this.PosDecButton.Location = new System.Drawing.Point(375, 245);
- this.PosDecButton.Name = "PosDecButton";
- this.PosDecButton.Size = new System.Drawing.Size(75, 54);
- this.PosDecButton.TabIndex = 0;
- this.PosDecButton.Text = "+ Dec";
- this.PosDecButton.UseVisualStyleBackColor = false;
- this.PosDecButton.Click += new System.EventHandler(this.PosDecButton_Click);
- //
- // NegDecButton
- //
- this.NegDecButton.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
- this.NegDecButton.BackColor = System.Drawing.Color.LightGray;
- this.NegDecButton.Location = new System.Drawing.Point(375, 317);
- this.NegDecButton.Name = "NegDecButton";
- this.NegDecButton.Size = new System.Drawing.Size(75, 54);
- this.NegDecButton.TabIndex = 1;
- this.NegDecButton.Text = "- Dec";
- this.NegDecButton.UseVisualStyleBackColor = false;
- this.NegDecButton.Click += new System.EventHandler(this.NegDecButton_Click);
- //
- // NegRAButton
- //
- this.NegRAButton.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
- this.NegRAButton.BackColor = System.Drawing.Color.LightGray;
- this.NegRAButton.Location = new System.Drawing.Point(281, 317);
- this.NegRAButton.Name = "NegRAButton";
- this.NegRAButton.Size = new System.Drawing.Size(75, 54);
- this.NegRAButton.TabIndex = 2;
- this.NegRAButton.Text = "- RA";
- this.NegRAButton.UseVisualStyleBackColor = false;
- this.NegRAButton.Click += new System.EventHandler(this.NegRAButton_Click);
- //
- // PosRAButton
- //
- this.PosRAButton.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
- this.PosRAButton.BackColor = System.Drawing.Color.LightGray;
- this.PosRAButton.Location = new System.Drawing.Point(471, 317);
- this.PosRAButton.Name = "PosRAButton";
- this.PosRAButton.Size = new System.Drawing.Size(75, 54);
- this.PosRAButton.TabIndex = 3;
- this.PosRAButton.Text = "+ RA";
- this.PosRAButton.UseVisualStyleBackColor = false;
- this.PosRAButton.Click += new System.EventHandler(this.PosRAButton_Click);
- //
- // CalibrateButton
- //
- this.CalibrateButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
- this.CalibrateButton.BackColor = System.Drawing.Color.LightGray;
- this.CalibrateButton.Location = new System.Drawing.Point(44, 326);
- this.CalibrateButton.Name = "CalibrateButton";
- this.CalibrateButton.Size = new System.Drawing.Size(123, 36);
- this.CalibrateButton.TabIndex = 4;
- this.CalibrateButton.Text = "Calibrate";
- this.CalibrateButton.UseVisualStyleBackColor = false;
- this.CalibrateButton.Click += new System.EventHandler(this.CalibrateButton_Click);
- //
- // ActualRATextBox
- //
- this.ActualRATextBox.Anchor = System.Windows.Forms.AnchorStyles.Left;
- this.ActualRATextBox.Location = new System.Drawing.Point(57, 149);
- this.ActualRATextBox.Name = "ActualRATextBox";
- this.ActualRATextBox.ReadOnly = true;
- this.ActualRATextBox.Size = new System.Drawing.Size(100, 20);
- this.ActualRATextBox.TabIndex = 5;
- //
- // ActualDecTextBox
- //
- this.ActualDecTextBox.Anchor = System.Windows.Forms.AnchorStyles.Left;
- this.ActualDecTextBox.Location = new System.Drawing.Point(57, 202);
- this.ActualDecTextBox.Name = "ActualDecTextBox";
- this.ActualDecTextBox.ReadOnly = true;
- this.ActualDecTextBox.Size = new System.Drawing.Size(100, 20);
- this.ActualDecTextBox.TabIndex = 6;
- //
- // ActualPositionLabel
- //
- this.ActualPositionLabel.Anchor = System.Windows.Forms.AnchorStyles.Left;
- this.ActualPositionLabel.AutoSize = true;
- this.ActualPositionLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F);
- this.ActualPositionLabel.Location = new System.Drawing.Point(53, 101);
- this.ActualPositionLabel.Name = "ActualPositionLabel";
- this.ActualPositionLabel.Size = new System.Drawing.Size(114, 20);
- this.ActualPositionLabel.TabIndex = 7;
- this.ActualPositionLabel.Text = "Actual Position";
- //
- // ActualRALabel
- //
- this.ActualRALabel.Anchor = System.Windows.Forms.AnchorStyles.Left;
- this.ActualRALabel.AutoSize = true;
- this.ActualRALabel.Location = new System.Drawing.Point(55, 131);
- this.ActualRALabel.Name = "ActualRALabel";
- this.ActualRALabel.Size = new System.Drawing.Size(84, 13);
- this.ActualRALabel.TabIndex = 8;
- this.ActualRALabel.Text = "Right Ascension";
- //
- // ActualDecLabel
- //
- this.ActualDecLabel.Anchor = System.Windows.Forms.AnchorStyles.Left;
- this.ActualDecLabel.AutoSize = true;
- this.ActualDecLabel.Location = new System.Drawing.Point(55, 184);
- this.ActualDecLabel.Name = "ActualDecLabel";
- this.ActualDecLabel.Size = new System.Drawing.Size(60, 13);
- this.ActualDecLabel.TabIndex = 9;
- this.ActualDecLabel.Text = "Declination";
- //
- // TargetDecLabel
- //
- this.TargetDecLabel.Anchor = System.Windows.Forms.AnchorStyles.Right;
- this.TargetDecLabel.AutoSize = true;
- this.TargetDecLabel.Location = new System.Drawing.Point(639, 184);
- this.TargetDecLabel.Name = "TargetDecLabel";
- this.TargetDecLabel.Size = new System.Drawing.Size(60, 13);
- this.TargetDecLabel.TabIndex = 14;
- this.TargetDecLabel.Text = "Declination";
- //
- // TargetRALabel
- //
- this.TargetRALabel.Anchor = System.Windows.Forms.AnchorStyles.Right;
- this.TargetRALabel.AutoSize = true;
- this.TargetRALabel.Location = new System.Drawing.Point(640, 131);
- this.TargetRALabel.Name = "TargetRALabel";
- this.TargetRALabel.Size = new System.Drawing.Size(84, 13);
- this.TargetRALabel.TabIndex = 13;
- this.TargetRALabel.Text = "Right Ascension";
- //
- // TargetPositionLabel
- //
- this.TargetPositionLabel.Anchor = System.Windows.Forms.AnchorStyles.Right;
- this.TargetPositionLabel.AutoSize = true;
- this.TargetPositionLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F);
- this.TargetPositionLabel.Location = new System.Drawing.Point(638, 101);
- this.TargetPositionLabel.Name = "TargetPositionLabel";
- this.TargetPositionLabel.Size = new System.Drawing.Size(115, 20);
- this.TargetPositionLabel.TabIndex = 12;
- this.TargetPositionLabel.Text = "Target Position";
- //
- // TargetDecTextBox
- //
- this.TargetDecTextBox.Anchor = System.Windows.Forms.AnchorStyles.Right;
- this.TargetDecTextBox.Location = new System.Drawing.Point(641, 202);
- this.TargetDecTextBox.Name = "TargetDecTextBox";
- this.TargetDecTextBox.ReadOnly = true;
- this.TargetDecTextBox.Size = new System.Drawing.Size(100, 20);
- this.TargetDecTextBox.TabIndex = 11;
- //
- // TargetRATextBox
- //
- this.TargetRATextBox.Anchor = System.Windows.Forms.AnchorStyles.Right;
- this.TargetRATextBox.Location = new System.Drawing.Point(641, 149);
- this.TargetRATextBox.Name = "TargetRATextBox";
- this.TargetRATextBox.ReadOnly = true;
- this.TargetRATextBox.Size = new System.Drawing.Size(100, 20);
- this.TargetRATextBox.TabIndex = 10;
- //
- // Title
- //
- this.Title.Anchor = System.Windows.Forms.AnchorStyles.Top;
- this.Title.AutoSize = true;
- this.Title.Font = new System.Drawing.Font("Microsoft Sans Serif", 30F);
- this.Title.Location = new System.Drawing.Point(297, 28);
- this.Title.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
- this.Title.Name = "Title";
- this.Title.Size = new System.Drawing.Size(242, 46);
- this.Title.TabIndex = 15;
- this.Title.Text = "Free Control";
- //
- // timer1
- //
- this.timer1.Enabled = true;
- this.timer1.Interval = 1000;
- this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
- //
- // IncrementButtons
- //
- this.IncrementButtons.Anchor = System.Windows.Forms.AnchorStyles.Top;
- this.IncrementButtons.Controls.Add(this.tenButton);
- this.IncrementButtons.Controls.Add(this.fiveButton);
- this.IncrementButtons.Controls.Add(this.oneButton);
- this.IncrementButtons.Controls.Add(this.oneForthButton);
- this.IncrementButtons.Location = new System.Drawing.Point(293, 113);
- this.IncrementButtons.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
- this.IncrementButtons.Name = "IncrementButtons";
- this.IncrementButtons.Padding = new System.Windows.Forms.Padding(2, 2, 2, 2);
- this.IncrementButtons.Size = new System.Drawing.Size(241, 77);
- this.IncrementButtons.TabIndex = 16;
- this.IncrementButtons.TabStop = false;
- this.IncrementButtons.Text = "Increment";
- //
- // tenButton
- //
- this.tenButton.BackColor = System.Drawing.Color.LightGray;
- this.tenButton.Location = new System.Drawing.Point(182, 18);
- this.tenButton.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
- this.tenButton.Name = "tenButton";
- this.tenButton.Size = new System.Drawing.Size(54, 54);
- this.tenButton.TabIndex = 3;
- this.tenButton.Text = "10";
- this.tenButton.UseVisualStyleBackColor = false;
- this.tenButton.Click += new System.EventHandler(this.tenButton_Click);
- //
- // fiveButton
- //
- this.fiveButton.BackColor = System.Drawing.Color.LightGray;
- this.fiveButton.Location = new System.Drawing.Point(124, 18);
- this.fiveButton.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
- this.fiveButton.Name = "fiveButton";
- this.fiveButton.Size = new System.Drawing.Size(54, 54);
- this.fiveButton.TabIndex = 2;
- this.fiveButton.Text = "5";
- this.fiveButton.UseVisualStyleBackColor = false;
- this.fiveButton.Click += new System.EventHandler(this.fiveButton_Click);
- //
- // oneButton
- //
- this.oneButton.BackColor = System.Drawing.Color.LightGray;
- this.oneButton.Location = new System.Drawing.Point(65, 18);
- this.oneButton.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
- this.oneButton.Name = "oneButton";
- this.oneButton.Size = new System.Drawing.Size(54, 54);
- this.oneButton.TabIndex = 1;
- this.oneButton.Text = "1";
- this.oneButton.UseVisualStyleBackColor = false;
- this.oneButton.Click += new System.EventHandler(this.oneButton_Click);
- //
- // oneForthButton
- //
- this.oneForthButton.BackColor = System.Drawing.Color.LightGray;
- this.oneForthButton.Location = new System.Drawing.Point(7, 18);
- this.oneForthButton.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
- this.oneForthButton.Name = "oneForthButton";
- this.oneForthButton.Size = new System.Drawing.Size(54, 54);
- this.oneForthButton.TabIndex = 0;
- this.oneForthButton.Text = "0.25";
- this.oneForthButton.UseVisualStyleBackColor = false;
- this.oneForthButton.Click += new System.EventHandler(this.oneForthButton_Click);
- //
- // editButton
- //
- this.editButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
- this.editButton.BackColor = System.Drawing.Color.LightGray;
- this.editButton.Location = new System.Drawing.Point(630, 326);
- this.editButton.Name = "editButton";
- this.editButton.Size = new System.Drawing.Size(123, 36);
- this.editButton.TabIndex = 17;
- this.editButton.Text = "Edit Position";
- this.editButton.UseVisualStyleBackColor = false;
- this.editButton.Click += new System.EventHandler(this.editButton_Click);
- //
- // errorLabel
- //
- this.errorLabel.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
- this.errorLabel.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
- this.errorLabel.ForeColor = System.Drawing.Color.Red;
- this.errorLabel.Location = new System.Drawing.Point(300, 411);
- this.errorLabel.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
- this.errorLabel.Name = "errorLabel";
- this.errorLabel.Size = new System.Drawing.Size(230, 19);
- this.errorLabel.TabIndex = 18;
- this.errorLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
- //
- // FreeControlForm
- //
- this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
- this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
- this.ClientSize = new System.Drawing.Size(800, 450);
- this.Controls.Add(this.errorLabel);
- this.Controls.Add(this.editButton);
- this.Controls.Add(this.IncrementButtons);
- this.Controls.Add(this.Title);
- this.Controls.Add(this.TargetDecLabel);
- this.Controls.Add(this.TargetRALabel);
- this.Controls.Add(this.TargetPositionLabel);
- this.Controls.Add(this.TargetDecTextBox);
- this.Controls.Add(this.TargetRATextBox);
- this.Controls.Add(this.ActualDecLabel);
- this.Controls.Add(this.ActualRALabel);
- this.Controls.Add(this.ActualPositionLabel);
- this.Controls.Add(this.ActualDecTextBox);
- this.Controls.Add(this.ActualRATextBox);
- this.Controls.Add(this.CalibrateButton);
- this.Controls.Add(this.PosRAButton);
- this.Controls.Add(this.NegRAButton);
- this.Controls.Add(this.NegDecButton);
- this.Controls.Add(this.PosDecButton);
- this.MinimumSize = new System.Drawing.Size(816, 489);
- this.Name = "FreeControlForm";
- this.Text = "FreeControlForm";
- this.IncrementButtons.ResumeLayout(false);
- this.ResumeLayout(false);
- this.PerformLayout();
-
- }
-
- #endregion
-
- private System.Windows.Forms.Button PosDecButton;
- private System.Windows.Forms.Button NegDecButton;
- private System.Windows.Forms.Button NegRAButton;
- private System.Windows.Forms.Button PosRAButton;
- private System.Windows.Forms.Button CalibrateButton;
- private System.Windows.Forms.TextBox ActualRATextBox;
- private System.Windows.Forms.TextBox ActualDecTextBox;
- private System.Windows.Forms.Label ActualPositionLabel;
- private System.Windows.Forms.Label ActualRALabel;
- private System.Windows.Forms.Label ActualDecLabel;
- private System.Windows.Forms.Label TargetDecLabel;
- private System.Windows.Forms.Label TargetRALabel;
- private System.Windows.Forms.Label TargetPositionLabel;
- private System.Windows.Forms.TextBox TargetDecTextBox;
- private System.Windows.Forms.TextBox TargetRATextBox;
- private System.Windows.Forms.Label Title;
- private System.Windows.Forms.Timer timer1;
- private System.Windows.Forms.GroupBox IncrementButtons;
- private System.Windows.Forms.Button tenButton;
- private System.Windows.Forms.Button fiveButton;
- private System.Windows.Forms.Button oneButton;
- private System.Windows.Forms.Button oneForthButton;
- private System.Windows.Forms.Button editButton;
- private System.Windows.Forms.Label errorLabel;
- }
-}
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/GUI/FreeControlForm.cs b/ControlRoomApplication/ControlRoomApplication/GUI/FreeControlForm.cs
deleted file mode 100644
index b2895ee5..00000000
--- a/ControlRoomApplication/ControlRoomApplication/GUI/FreeControlForm.cs
+++ /dev/null
@@ -1,330 +0,0 @@
-using ControlRoomApplication.Controllers;
-using ControlRoomApplication.Database;
-using ControlRoomApplication.Entities;
-using System;
-using System.Windows.Forms;
-
-namespace ControlRoomApplication.Main
-{
- public partial class FreeControlForm : Form
- {
- public Appointment CurrentAppointment { get; set; }
- public Coordinate TargetCoordinate { get; set; }
- public double Increment { get; set; }
- public CoordinateCalculationController CoordCalc { set; get; }
- public ControlRoom controlRoom { get; set; }
- public int rtId { get; set; }
- private static readonly log4net.ILog logger =
- log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
-
- public FreeControlForm(ControlRoom new_controlRoom, int new_rtId)
- {
- InitializeComponent();
- // Set ControlRoom
- controlRoom = new_controlRoom;
- // Set RT id
- rtId = new_rtId;
- // Make coordCalc
- CoordCalc = controlRoom.RadioTelescopeControllers[rtId - 1].CoordinateController;
- // Set increment
- Increment = 1;
- UpdateIncrementButtons();
- // Add free control appt
- CurrentAppointment = new Appointment();
- CurrentAppointment.StartTime = DateTime.UtcNow.AddSeconds(5);
- CurrentAppointment.EndTime = DateTime.UtcNow.AddMinutes(15);
- CurrentAppointment.Status = AppointmentStatusEnum.REQUESTED;
- CurrentAppointment.Type = AppointmentTypeEnum.FREE_CONTROL;
- CurrentAppointment.SpectraCyberConfig = new SpectraCyberConfig(SpectraCyberModeTypeEnum.CONTINUUM);
- CurrentAppointment.TelescopeId = rtId;
- CurrentAppointment.UserId = 1;
- DatabaseOperations.AddAppointment(CurrentAppointment);
- //Calibrate Move
- CalibrateMove();
-
- logger.Info("FreeControl Form Initalized");
- }
-
- private void FreeControlForm_FormClosing(Object sender, FormClosingEventArgs e)
- {
- logger.Info("FreeControl Form Closing");
- timer1.Enabled = false;
- }
-
- private void PosDecButton_Click(object sender, EventArgs e)
- {
- logger.Info("Positive Declination Button Clicked");
- Coordinate new_coord = new Coordinate(TargetCoordinate.RightAscension, TargetCoordinate.Declination + Increment);
- Entities.Orientation test_orientation = CoordCalc.CoordinateToOrientation(new_coord, DateTime.UtcNow);
- if(test_orientation.Azimuth > 0 && test_orientation.Elevation > 0)
- {
- TargetCoordinate = new_coord;
- CoordMove();
- }
- else
- {
- errorLabel.Text = "Invalid Coordinate: orienation out of range";
- }
- }
-
- private void NegDecButton_Click(object sender, EventArgs e)
- {
- logger.Info("Negitive Declination Button Clicked");
- Coordinate new_coord = new Coordinate(TargetCoordinate.RightAscension, TargetCoordinate.Declination - Increment);
- Entities.Orientation test_orientation = CoordCalc.CoordinateToOrientation(new_coord, DateTime.UtcNow);
- if (test_orientation.Azimuth > 0 && test_orientation.Elevation > 0)
- {
- TargetCoordinate = new_coord;
- CoordMove();
- }
- else
- {
- errorLabel.Text = "Invalid Coordinate: orienation out of range";
- }
- }
-
- private void NegRAButton_Click(object sender, EventArgs e)
- {
- logger.Info("Negitive Right Ascension Button Clicked");
- Coordinate new_coord = new Coordinate(TargetCoordinate.RightAscension - Increment, TargetCoordinate.Declination);
- Entities.Orientation test_orientation = CoordCalc.CoordinateToOrientation(new_coord, DateTime.UtcNow);
- if (test_orientation.Azimuth > 0 && test_orientation.Elevation > 0)
- {
- TargetCoordinate = new_coord;
- CoordMove();
- }
- else
- {
- errorLabel.Text = "Invalid Coordinate: orienation out of range";
- }
- }
-
- private void PosRAButton_Click(object sender, EventArgs e)
- {
- logger.Info("Positive Right Ascension Button Clicked");
- Coordinate new_coord = new Coordinate(TargetCoordinate.RightAscension + Increment, TargetCoordinate.Declination);
- Entities.Orientation test_orientation = CoordCalc.CoordinateToOrientation(new_coord, DateTime.UtcNow);
- if (test_orientation.Azimuth >= 0 && test_orientation.Elevation >= 0)
- {
- TargetCoordinate = new_coord;
- CoordMove();
- }
- else
- {
- errorLabel.Text = "Invalid Coordinate: orienation out of range";
- }
- }
-
- private void CalibrateButton_Click(object sender, EventArgs e)
- {
- logger.Info("Calibrate Button Clicked");
- CalibrateMove();
- }
-
- public void CalibrateMove()
- {
- logger.Info("CalibrateMove ");
- CurrentAppointment = DatabaseOperations.GetUpdatedAppointment(CurrentAppointment.Id);
- CurrentAppointment.Orientation = new Entities.Orientation(0, 90);
- DatabaseOperations.UpdateAppointment(CurrentAppointment);
- TargetCoordinate = CoordCalc.OrientationToCoordinate(CurrentAppointment.Orientation, DateTime.UtcNow);
- UpdateText();
- }
-
- private void CoordMove()
- {
- logger.Info("CoordMove ");
- CurrentAppointment = DatabaseOperations.GetUpdatedAppointment(CurrentAppointment.Id);
- CurrentAppointment.Coordinates.Add(TargetCoordinate);
- DatabaseOperations.UpdateAppointment(CurrentAppointment);
- UpdateText();
- }
-
- private void UpdateText()
- {
- string RA = TargetCoordinate.RightAscension.ToString("0.##");
- string Dec = TargetCoordinate.Declination.ToString("0.##");
- logger.Info("UpdateText, Target Coordinate = RA:" + RA + ", Dec:" + Dec);
- SetTargetRAText(RA);
- SetTargetDecText(Dec);
- errorLabel.Text = "Free Control for Radio Telescope " + rtId.ToString();
- }
-
- private void timer1_Tick(object sender, EventArgs e)
- {
- Entities.Orientation currentOrienation = controlRoom.RadioTelescopeControllers[rtId - 1].GetCurrentOrientation();
- Coordinate ConvertedPosition = CoordCalc.OrientationToCoordinate(currentOrienation, DateTime.UtcNow);
- SetActualRAText(ConvertedPosition.RightAscension.ToString("0.##"));
- SetActualDecText(ConvertedPosition.Declination.ToString("0.##"));
- }
-
- delegate void SetTargetRATextCallback(string text);
- private void SetTargetRAText(string text)
- {
- // InvokeRequired required compares the thread ID of the
- // calling thread to the thread ID of the creating thread.
- // If these threads are different, it returns true.
- if (TargetRATextBox.InvokeRequired)
- {
- SetTargetRATextCallback d = new SetTargetRATextCallback(SetTargetRAText);
- Invoke(d, new object[] { text });
- }
- else
- {
- TargetRATextBox.Text = text;
- }
- }
-
- delegate void SetTargetDecTextCallback(string text);
- private void SetTargetDecText(string text)
- {
- // InvokeRequired required compares the thread ID of the
- // calling thread to the thread ID of the creating thread.
- // If these threads are different, it returns true.
- if (TargetDecTextBox.InvokeRequired)
- {
- SetTargetDecTextCallback d = new SetTargetDecTextCallback(SetTargetDecText);
- Invoke(d, new object[] { text });
- }
- else
- {
- TargetDecTextBox.Text = text;
- }
- }
-
- delegate void SetActualRATextCallback(string text);
- private void SetActualRAText(string text)
- {
- // InvokeRequired required compares the thread ID of the
- // calling thread to the thread ID of the creating thread.
- // If these threads are different, it returns true.
- if (ActualRATextBox.InvokeRequired)
- {
- SetActualRATextCallback d = new SetActualRATextCallback(SetActualRAText);
- try
- {
- Invoke(d, new object[] { text });
-
- }
- catch (Exception e) { }
- }
- else
- {
- ActualRATextBox.Text = text;
- }
- }
-
- delegate void SetActualDecTextCallback(string text);
- private void SetActualDecText(string text)
- {
- // InvokeRequired required compares the thread ID of the
- // calling thread to the thread ID of the creating thread.
- // If these threads are different, it returns true.
- if (ActualDecTextBox.InvokeRequired)
- {
- SetActualDecTextCallback d = new SetActualDecTextCallback(SetActualDecText);
- try
- {
- Invoke(d, new object[] { text });
-
- }
- catch (Exception e) { }
- }
- else
- {
- ActualDecTextBox.Text = text;
- }
- }
-
- private void oneForthButton_Click(object sender, EventArgs e)
- {
- logger.Info("Increment = 0.25 Button Clicked");
- Increment = 0.25;
- UpdateIncrementButtons();
- }
-
- private void oneButton_Click(object sender, EventArgs e)
- {
- logger.Info("Increment = 1 Button Clicked");
- Increment = 1;
- UpdateIncrementButtons();
- }
-
- private void fiveButton_Click(object sender, EventArgs e)
- {
- logger.Info("Increment = 5 Button Clicked");
- Increment = 5;
- UpdateIncrementButtons();
- }
-
- private void tenButton_Click(object sender, EventArgs e)
- {
- logger.Info("Increment = 10 Button Clicked");
- Increment = 10;
- UpdateIncrementButtons();
- }
-
- private void UpdateIncrementButtons()
- {
- oneForthButton.BackColor = System.Drawing.Color.LightGray;
- oneButton.BackColor = System.Drawing.Color.LightGray;
- fiveButton.BackColor = System.Drawing.Color.LightGray;
- tenButton.BackColor = System.Drawing.Color.LightGray;
-
- switch (Increment)
- {
- case 0.25:
- oneForthButton.BackColor = System.Drawing.Color.DarkGray;
- break;
- case 1:
- oneButton.BackColor = System.Drawing.Color.DarkGray;
- break;
- case 5:
- fiveButton.BackColor = System.Drawing.Color.DarkGray;
- break;
- case 10:
- tenButton.BackColor = System.Drawing.Color.DarkGray;
- break;
- default:
- throw new ArgumentException("Invalid Increment");
- }
- }
-
- private void editButton_Click(object sender, EventArgs e)
- {
- logger.Info("Edit Button Clicked");
- bool save_state = (editButton.Text == "Save Position");
- if (save_state)
- {
- editButton.Text = "Edit Position";
- double newRA;
- double newDec;
- double.TryParse(TargetRATextBox.Text, out newRA);
- double.TryParse(TargetDecTextBox.Text, out newDec);
- Coordinate new_coord = new Coordinate(newRA, newDec);
- Entities.Orientation test_orientation = CoordCalc.CoordinateToOrientation(new_coord, DateTime.UtcNow);
- if (test_orientation.Azimuth >= 0 && test_orientation.Elevation >= 0)
- {
- TargetCoordinate = new_coord;
- CoordMove();
- }
- else
- {
- errorLabel.Text = "Invalid Coordinate: orienation out of range";
- }
- }
- else
- {
- editButton.Text = "Save Position";
- }
-
- PosDecButton.Enabled = save_state;
- NegDecButton.Enabled = save_state;
- PosRAButton.Enabled = save_state;
- NegRAButton.Enabled = save_state;
- CalibrateButton.Enabled = save_state;
- TargetRATextBox.ReadOnly = save_state;
- TargetDecTextBox.ReadOnly = save_state;
- }
- }
-}
diff --git a/ControlRoomApplication/ControlRoomApplication/GUI/InputDialogs/CustomOrientationInputDialog.Designer.cs b/ControlRoomApplication/ControlRoomApplication/GUI/InputDialogs/CustomOrientationInputDialog.Designer.cs
new file mode 100644
index 00000000..5f5c6918
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/GUI/InputDialogs/CustomOrientationInputDialog.Designer.cs
@@ -0,0 +1,65 @@
+namespace ControlRoomApplication.GUI
+{
+ partial class CustomOrientationInputDialog
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.invalidInputLabel = new System.Windows.Forms.Label();
+ this.SuspendLayout();
+ //
+ // invalidInputLabel
+ //
+ this.invalidInputLabel.AutoSize = true;
+ this.invalidInputLabel.ForeColor = System.Drawing.Color.Red;
+ this.invalidInputLabel.Location = new System.Drawing.Point(139, 141);
+ this.invalidInputLabel.Name = "invalidInputLabel";
+ this.invalidInputLabel.Size = new System.Drawing.Size(64, 13);
+ this.invalidInputLabel.TabIndex = 4;
+ this.invalidInputLabel.Text = "Invalid input";
+ //
+ // CustomOrientationInputDialog
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(355, 237);
+ this.Controls.Add(this.invalidInputLabel);
+ this.Name = "CustomOrientationInputDialog";
+ this.Text = "AzimuthInputDialog";
+ this.Controls.SetChildIndex(this.promptLabel, 0);
+ this.Controls.SetChildIndex(this.textBox, 0);
+ this.Controls.SetChildIndex(this.okButton, 0);
+ this.Controls.SetChildIndex(this.invalidInputLabel, 0);
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Label invalidInputLabel;
+ }
+}
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/GUI/InputDialogs/CustomOrientationInputDialog.cs b/ControlRoomApplication/ControlRoomApplication/GUI/InputDialogs/CustomOrientationInputDialog.cs
new file mode 100644
index 00000000..dfc1c098
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/GUI/InputDialogs/CustomOrientationInputDialog.cs
@@ -0,0 +1,93 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using ControlRoomApplication.Constants;
+using ControlRoomApplication.Controllers;
+using ControlRoomApplication.Entities;
+
+namespace ControlRoomApplication.GUI
+{
+ public partial class CustomOrientationInputDialog : InputDialog
+ {
+ public double ElevationHighLimit { get; private set; }
+ public double ElevationLowLimit { get; private set; }
+ public double ElevationPos { get; private set; }
+ public double AzimuthPos { get; private set; }
+ public string[] Values;
+ private Regex rx;
+ double TempAz, TempElev;
+
+ public CustomOrientationInputDialog(bool EnableSoftwareStops, string teleType, double maxElevationDegrees, double minElevationDegrees)
+ {
+ InitializeComponent();
+
+ rx = new Regex(@"^[+-]?([0-9]+\.?[0-9]*|\.[0-9]+),[+-]?([0-9]+\.?[0-9]*|\.[0-9]+)$"); // Regex statement to validate input (Format of #,#)
+
+ okButton.Enabled = false; // Disable the OK button by default
+ invalidInputLabel.Visible = false; // Don't show the invalid input label at first to avoid confusing the user
+
+ textBox.TextChanged += new EventHandler(TextBox_TextChanged);
+
+ if (EnableSoftwareStops) // Set limits depending on whether software stops are enabled or not
+ {
+ ElevationHighLimit = maxElevationDegrees;
+ ElevationLowLimit = minElevationDegrees;
+ }
+ else
+ {
+ ElevationHighLimit = SimulationConstants.LIMIT_HIGH_EL_DEGREES;
+ ElevationLowLimit = SimulationConstants.LIMIT_LOW_EL_DEGREES;
+ }
+
+ promptLabel.Text = "The Radio Telescope is currently set to be type " + teleType + "." +
+ " This script is best run with a telescope type of SLIP_RING.\n\n" +
+ "Please type an a custom orientation containing azimuth between 0 and 360 degrees," +
+ " and elevation between " + ElevationLowLimit + " and " + ElevationHighLimit +
+ " degrees. Format the entry as a comma-separated list in the format " +
+ "azimuth, elevation. Ex: 55,80";
+ }
+
+ public void SetPrompt(string text)
+ {
+ promptLabel.Text = text;
+ }
+
+ public void TextBox_TextChanged(Object sender, EventArgs e)
+ {
+ if (rx.IsMatch(textBox.Text))
+ {
+ Values = textBox.Text.Split(',');
+
+ Double.TryParse(Values[0], out TempAz);
+ Double.TryParse(Values[1], out TempElev);
+
+ AzimuthPos = TempAz;
+ ElevationPos = TempElev;
+
+ // Enable the OK button and hide the invalid input label if the input is valid. Otherwise grey out the OK button and hide the label.
+ if ((AzimuthPos > 360 || AzimuthPos < 0) || (ElevationPos > ElevationHighLimit || ElevationPos < ElevationLowLimit))
+ {
+ okButton.Enabled = false;
+ invalidInputLabel.Visible = true;
+ }
+ else
+ {
+ okButton.Enabled = true;
+ invalidInputLabel.Visible = false;
+ }
+ }
+ else
+ {
+ okButton.Enabled = false;
+ invalidInputLabel.Visible = true;
+ }
+ }
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/GUI/InputDialogs/CustomOrientationInputDialog.resx b/ControlRoomApplication/ControlRoomApplication/GUI/InputDialogs/CustomOrientationInputDialog.resx
new file mode 100644
index 00000000..1af7de15
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/GUI/InputDialogs/CustomOrientationInputDialog.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/GUI/InputDialogs/InputDialog.Designer.cs b/ControlRoomApplication/ControlRoomApplication/GUI/InputDialogs/InputDialog.Designer.cs
new file mode 100644
index 00000000..59089098
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/GUI/InputDialogs/InputDialog.Designer.cs
@@ -0,0 +1,99 @@
+namespace ControlRoomApplication.GUI
+{
+ partial class InputDialog
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.promptLabel = new System.Windows.Forms.Label();
+ this.textBox = new System.Windows.Forms.TextBox();
+ this.okButton = new System.Windows.Forms.Button();
+ this.cancelButton = new System.Windows.Forms.Button();
+ this.SuspendLayout();
+ //
+ // promptLabel
+ //
+ this.promptLabel.AutoSize = true;
+ this.promptLabel.Location = new System.Drawing.Point(31, 27);
+ this.promptLabel.MaximumSize = new System.Drawing.Size(250, 0);
+ this.promptLabel.Name = "promptLabel";
+ this.promptLabel.Size = new System.Drawing.Size(35, 13);
+ this.promptLabel.TabIndex = 0;
+ this.promptLabel.Text = "label1";
+ //
+ // textBox
+ //
+ this.textBox.Location = new System.Drawing.Point(45, 166);
+ this.textBox.Name = "textBox";
+ this.textBox.Size = new System.Drawing.Size(257, 20);
+ this.textBox.TabIndex = 1;
+ //
+ // okButton
+ //
+ this.okButton.DialogResult = System.Windows.Forms.DialogResult.OK;
+ this.okButton.Location = new System.Drawing.Point(86, 202);
+ this.okButton.Name = "okButton";
+ this.okButton.Size = new System.Drawing.Size(75, 23);
+ this.okButton.TabIndex = 2;
+ this.okButton.Text = "OK";
+ this.okButton.UseVisualStyleBackColor = true;
+ //
+ // cancelButton
+ //
+ this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+ this.cancelButton.Location = new System.Drawing.Point(182, 202);
+ this.cancelButton.Name = "cancelButton";
+ this.cancelButton.Size = new System.Drawing.Size(75, 23);
+ this.cancelButton.TabIndex = 3;
+ this.cancelButton.Text = "Cancel";
+ this.cancelButton.UseVisualStyleBackColor = true;
+ //
+ // InputDialog
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.AutoSize = true;
+ this.ClientSize = new System.Drawing.Size(355, 237);
+ this.Controls.Add(this.cancelButton);
+ this.Controls.Add(this.okButton);
+ this.Controls.Add(this.textBox);
+ this.Controls.Add(this.promptLabel);
+ this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
+ this.Name = "InputDialog";
+ this.Text = "InputDialog";
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ protected System.Windows.Forms.Label promptLabel;
+ protected System.Windows.Forms.TextBox textBox;
+ protected System.Windows.Forms.Button okButton;
+ private System.Windows.Forms.Button cancelButton;
+ }
+}
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/GUI/InputDialogs/InputDialog.cs b/ControlRoomApplication/ControlRoomApplication/GUI/InputDialogs/InputDialog.cs
new file mode 100644
index 00000000..c44594b4
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/GUI/InputDialogs/InputDialog.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+///
+/// Input dialog box class that can be used for any string input
+///
+namespace ControlRoomApplication.GUI
+{
+ public partial class InputDialog : Form
+ {
+ public InputDialog()
+ {
+ InitializeComponent();
+ }
+
+ public void setPromptLabel(string text)
+ {
+ promptLabel.Text = text;
+ }
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/GUI/InputDialogs/InputDialog.resx b/ControlRoomApplication/ControlRoomApplication/GUI/InputDialogs/InputDialog.resx
new file mode 100644
index 00000000..1af7de15
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/GUI/InputDialogs/InputDialog.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/GUI/MainForm.Designer.cs b/ControlRoomApplication/ControlRoomApplication/GUI/MainForm.Designer.cs
index 1315a7b0..4db67bd9 100644
--- a/ControlRoomApplication/ControlRoomApplication/GUI/MainForm.Designer.cs
+++ b/ControlRoomApplication/ControlRoomApplication/GUI/MainForm.Designer.cs
@@ -7,6 +7,11 @@ partial class MainForm
///
private System.ComponentModel.IContainer components = null;
+ // Create error provider objects
+ // private System.Windows.Forms.ErrorProvider txtPLCPortErrorProvider = new System.Windows.Forms.ErrorProvider();
+ // txtPLCPortErrorProvider.SetIconAlignment(this.txtPLCPort, 2);
+
+
///
/// Clean up any resources being used.
///
@@ -28,291 +33,583 @@ protected override void Dispose(bool disposing)
///
private void InitializeComponent()
{
- System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle3 = new System.Windows.Forms.DataGridViewCellStyle();
- System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle4 = new System.Windows.Forms.DataGridViewCellStyle();
- this.button1 = new System.Windows.Forms.Button();
+ this.components = new System.ComponentModel.Container();
+ this.startButton = new System.Windows.Forms.Button();
this.dataGridView1 = new System.Windows.Forms.DataGridView();
- this.button2 = new System.Windows.Forms.Button();
+ this.shutdownButton = new System.Windows.Forms.Button();
this.txtPLCPort = new System.Windows.Forms.TextBox();
- this.comboBox1 = new System.Windows.Forms.ComboBox();
+ this.comboSpectraCyberBox = new System.Windows.Forms.ComboBox();
this.txtPLCIP = new System.Windows.Forms.TextBox();
- this.comboBox2 = new System.Windows.Forms.ComboBox();
- this.checkBox1 = new System.Windows.Forms.CheckBox();
+ this.comboWeatherStationBox = new System.Windows.Forms.ComboBox();
this.comboPLCType = new System.Windows.Forms.ComboBox();
- this.ManualControl = new System.Windows.Forms.Button();
this.FreeControl = new System.Windows.Forms.Button();
- this.comboEncoderType = new System.Windows.Forms.ComboBox();
- this.comboMicrocontrollerBox = new System.Windows.Forms.ComboBox();
+ this.comboSensorNetworkBox = new System.Windows.Forms.ComboBox();
this.loopBackBox = new System.Windows.Forms.CheckBox();
this.LocalIPCombo = new System.Windows.Forms.ComboBox();
this.label1 = new System.Windows.Forms.Label();
+ this.simulationSettingsGroupbox = new System.Windows.Forms.GroupBox();
+ this.label8 = new System.Windows.Forms.Label();
+ this.txtSpectraPort = new System.Windows.Forms.TextBox();
+ this.label2 = new System.Windows.Forms.Label();
+ this.RLLabel = new System.Windows.Forms.Label();
+ this.txtWSCOMPort = new System.Windows.Forms.TextBox();
+ this.txtRemoteListenerCOMPort = new System.Windows.Forms.TextBox();
+ this.label3 = new System.Windows.Forms.Label();
+ this.label4 = new System.Windows.Forms.Label();
+ this.portGroupbox = new System.Windows.Forms.GroupBox();
+ this.label7 = new System.Windows.Forms.Label();
+ this.label6 = new System.Windows.Forms.Label();
+ this.sensorNetworkClientPort = new System.Windows.Forms.TextBox();
+ this.sensorNetworkClientIPAddress = new System.Windows.Forms.TextBox();
+ this.sensorNetworkServerPort = new System.Windows.Forms.TextBox();
+ this.sensorNetworkServerIPAddress = new System.Windows.Forms.TextBox();
+ this.txtMcuCOMPort = new System.Windows.Forms.TextBox();
+ this.label5 = new System.Windows.Forms.Label();
+ this.acceptSettings = new System.Windows.Forms.Button();
+ this.startRTGroupbox = new System.Windows.Forms.GroupBox();
+ this.helpButton = new System.Windows.Forms.Button();
+ this.ProdcheckBox = new System.Windows.Forms.CheckBox();
+ this.MCUIPToolTip = new System.Windows.Forms.ToolTip(this.components);
+ this.MCUPortToolTip = new System.Windows.Forms.ToolTip(this.components);
+ this.PLCPortToolTip = new System.Windows.Forms.ToolTip(this.components);
+ this.RLPortToolTip = new System.Windows.Forms.ToolTip(this.components);
+ this.WCOMPortToolTip = new System.Windows.Forms.ToolTip(this.components);
((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit();
+ this.simulationSettingsGroupbox.SuspendLayout();
+ this.portGroupbox.SuspendLayout();
+ this.startRTGroupbox.SuspendLayout();
this.SuspendLayout();
//
- // button1
- //
- this.button1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
- this.button1.BackColor = System.Drawing.Color.LimeGreen;
- this.button1.Font = new System.Drawing.Font("Microsoft Sans Serif", 18F);
- this.button1.ForeColor = System.Drawing.Color.Black;
- this.button1.Location = new System.Drawing.Point(1221, 527);
- this.button1.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2);
- this.button1.Name = "button1";
- this.button1.Size = new System.Drawing.Size(249, 89);
- this.button1.TabIndex = 6;
- this.button1.Text = "Start Telescope";
- this.button1.UseVisualStyleBackColor = false;
- this.button1.Click += new System.EventHandler(this.button1_Click);
+ // startButton
+ //
+ this.startButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+ this.startButton.BackColor = System.Drawing.Color.LimeGreen;
+ this.startButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
+ this.startButton.Font = new System.Drawing.Font("Microsoft Sans Serif", 18F);
+ this.startButton.ForeColor = System.Drawing.Color.Black;
+ this.startButton.Location = new System.Drawing.Point(197, 68);
+ this.startButton.Margin = new System.Windows.Forms.Padding(2);
+ this.startButton.Name = "startButton";
+ this.startButton.Size = new System.Drawing.Size(170, 40);
+ this.startButton.TabIndex = 6;
+ this.startButton.Text = "Start RT";
+ this.startButton.UseVisualStyleBackColor = false;
+ this.startButton.Click += new System.EventHandler(this.startButton_Click);
//
// dataGridView1
//
this.dataGridView1.AllowUserToAddRows = false;
this.dataGridView1.AllowUserToDeleteRows = false;
this.dataGridView1.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.Fill;
- dataGridViewCellStyle3.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
- dataGridViewCellStyle3.BackColor = System.Drawing.SystemColors.Control;
- dataGridViewCellStyle3.Font = new System.Drawing.Font("Microsoft Sans Serif", 14F);
- dataGridViewCellStyle3.ForeColor = System.Drawing.SystemColors.WindowText;
- dataGridViewCellStyle3.SelectionBackColor = System.Drawing.SystemColors.Highlight;
- dataGridViewCellStyle3.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
- dataGridViewCellStyle3.WrapMode = System.Windows.Forms.DataGridViewTriState.True;
- this.dataGridView1.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle3;
+ this.dataGridView1.BackgroundColor = System.Drawing.Color.Gainsboro;
this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
- dataGridViewCellStyle4.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
- dataGridViewCellStyle4.BackColor = System.Drawing.SystemColors.Window;
- dataGridViewCellStyle4.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F);
- dataGridViewCellStyle4.ForeColor = System.Drawing.SystemColors.ControlText;
- dataGridViewCellStyle4.SelectionBackColor = System.Drawing.SystemColors.Highlight;
- dataGridViewCellStyle4.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
- dataGridViewCellStyle4.WrapMode = System.Windows.Forms.DataGridViewTriState.False;
- this.dataGridView1.DefaultCellStyle = dataGridViewCellStyle4;
- this.dataGridView1.Location = new System.Drawing.Point(12, 28);
- this.dataGridView1.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2);
+ this.dataGridView1.GridColor = System.Drawing.SystemColors.ActiveCaptionText;
+ this.dataGridView1.Location = new System.Drawing.Point(11, 22);
+ this.dataGridView1.Margin = new System.Windows.Forms.Padding(2);
this.dataGridView1.Name = "dataGridView1";
+ this.dataGridView1.RowHeadersWidthSizeMode = System.Windows.Forms.DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders;
this.dataGridView1.RowTemplate.Height = 24;
this.dataGridView1.RowTemplate.ReadOnly = true;
- this.dataGridView1.Size = new System.Drawing.Size(537, 283);
+ this.dataGridView1.Size = new System.Drawing.Size(509, 230);
this.dataGridView1.TabIndex = 7;
this.dataGridView1.CellContentClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView1_CellContentClick);
//
- // button2
- //
- this.button2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
- this.button2.BackColor = System.Drawing.Color.Red;
- this.button2.Font = new System.Drawing.Font("Microsoft Sans Serif", 18F);
- this.button2.Location = new System.Drawing.Point(1221, 640);
- this.button2.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2);
- this.button2.Name = "button2";
- this.button2.Size = new System.Drawing.Size(249, 84);
- this.button2.TabIndex = 7;
- this.button2.Text = "Shut Down Telescope";
- this.button2.UseVisualStyleBackColor = false;
- this.button2.Click += new System.EventHandler(this.button2_Click);
+ // shutdownButton
+ //
+ this.shutdownButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+ this.shutdownButton.BackColor = System.Drawing.Color.Red;
+ this.shutdownButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
+ this.shutdownButton.Font = new System.Drawing.Font("Microsoft Sans Serif", 18F);
+ this.shutdownButton.Location = new System.Drawing.Point(13, 68);
+ this.shutdownButton.Margin = new System.Windows.Forms.Padding(2);
+ this.shutdownButton.Name = "shutdownButton";
+ this.shutdownButton.Size = new System.Drawing.Size(170, 40);
+ this.shutdownButton.TabIndex = 7;
+ this.shutdownButton.Text = "Shutdown RT";
+ this.shutdownButton.UseVisualStyleBackColor = false;
+ this.shutdownButton.Click += new System.EventHandler(this.button2_Click);
//
// txtPLCPort
//
this.txtPLCPort.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+ this.txtPLCPort.BackColor = System.Drawing.Color.Gainsboro;
this.txtPLCPort.Font = new System.Drawing.Font("Microsoft Sans Serif", 14F);
- this.txtPLCPort.Location = new System.Drawing.Point(709, 703);
- this.txtPLCPort.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2);
+ this.txtPLCPort.Location = new System.Drawing.Point(249, 49);
+ this.txtPLCPort.Margin = new System.Windows.Forms.Padding(2);
this.txtPLCPort.Name = "txtPLCPort";
- this.txtPLCPort.Size = new System.Drawing.Size(151, 34);
+ this.txtPLCPort.Size = new System.Drawing.Size(118, 29);
this.txtPLCPort.TabIndex = 5;
- this.txtPLCPort.Text = "PLC Port";
- this.txtPLCPort.GotFocus += new System.EventHandler(this.textBox1_Focus);
+ this.txtPLCPort.TextChanged += new System.EventHandler(this.txtPLCPort_TextChanged);
//
- // comboBox1
+ // comboSpectraCyberBox
//
- this.comboBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
- this.comboBox1.Font = new System.Drawing.Font("Microsoft Sans Serif", 14F);
- this.comboBox1.FormattingEnabled = true;
- this.comboBox1.Items.AddRange(new object[] {
+ this.comboSpectraCyberBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+ this.comboSpectraCyberBox.BackColor = System.Drawing.Color.WhiteSmoke;
+ this.comboSpectraCyberBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.comboSpectraCyberBox.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.comboSpectraCyberBox.FormattingEnabled = true;
+ this.comboSpectraCyberBox.Items.AddRange(new object[] {
"Production SpectraCyber",
"Simulated SpectraCyber"});
- this.comboBox1.Location = new System.Drawing.Point(371, 700);
- this.comboBox1.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2);
- this.comboBox1.Name = "comboBox1";
- this.comboBox1.Size = new System.Drawing.Size(315, 37);
- this.comboBox1.TabIndex = 2;
- this.comboBox1.Text = "Simulated SpectraCyber";
+ this.comboSpectraCyberBox.Location = new System.Drawing.Point(6, 47);
+ this.comboSpectraCyberBox.Margin = new System.Windows.Forms.Padding(2);
+ this.comboSpectraCyberBox.Name = "comboSpectraCyberBox";
+ this.comboSpectraCyberBox.Size = new System.Drawing.Size(246, 28);
+ this.comboSpectraCyberBox.TabIndex = 2;
//
// txtPLCIP
//
this.txtPLCIP.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+ this.txtPLCIP.BackColor = System.Drawing.Color.Gainsboro;
this.txtPLCIP.Font = new System.Drawing.Font("Microsoft Sans Serif", 14F);
- this.txtPLCIP.Location = new System.Drawing.Point(709, 590);
- this.txtPLCIP.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2);
+ this.txtPLCIP.Location = new System.Drawing.Point(249, 13);
+ this.txtPLCIP.Margin = new System.Windows.Forms.Padding(2);
this.txtPLCIP.Name = "txtPLCIP";
- this.txtPLCIP.Size = new System.Drawing.Size(151, 34);
+ this.txtPLCIP.Size = new System.Drawing.Size(118, 29);
this.txtPLCIP.TabIndex = 4;
- this.txtPLCIP.Text = "PLC IP";
- this.txtPLCIP.GotFocus += new System.EventHandler(this.textBox2_Focus);
+ this.txtPLCIP.TextChanged += new System.EventHandler(this.txtPLCIP_TextChanged);
//
- // comboBox2
+ // comboWeatherStationBox
//
- this.comboBox2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
- this.comboBox2.Font = new System.Drawing.Font("Microsoft Sans Serif", 14F);
- this.comboBox2.FormattingEnabled = true;
- this.comboBox2.Items.AddRange(new object[] {
+ this.comboWeatherStationBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+ this.comboWeatherStationBox.BackColor = System.Drawing.Color.WhiteSmoke;
+ this.comboWeatherStationBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.comboWeatherStationBox.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.comboWeatherStationBox.FormattingEnabled = true;
+ this.comboWeatherStationBox.Items.AddRange(new object[] {
"Production Weather Station",
"Simulated Weather Station",
"Test Weather Station"});
- this.comboBox2.Location = new System.Drawing.Point(12, 700);
- this.comboBox2.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2);
- this.comboBox2.Name = "comboBox2";
- this.comboBox2.Size = new System.Drawing.Size(335, 37);
- this.comboBox2.TabIndex = 1;
- this.comboBox2.Text = "Simulated Weather Station";
- //
- // checkBox1
- //
- this.checkBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
- this.checkBox1.AutoSize = true;
- this.checkBox1.Font = new System.Drawing.Font("Microsoft Sans Serif", 14F);
- this.checkBox1.Location = new System.Drawing.Point(12, 657);
- this.checkBox1.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2);
- this.checkBox1.Name = "checkBox1";
- this.checkBox1.Size = new System.Drawing.Size(293, 33);
- this.checkBox1.TabIndex = 0;
- this.checkBox1.Text = "Populate local database";
- this.checkBox1.UseVisualStyleBackColor = true;
+ this.comboWeatherStationBox.Location = new System.Drawing.Point(5, 77);
+ this.comboWeatherStationBox.Margin = new System.Windows.Forms.Padding(2);
+ this.comboWeatherStationBox.Name = "comboWeatherStationBox";
+ this.comboWeatherStationBox.Size = new System.Drawing.Size(247, 28);
+ this.comboWeatherStationBox.TabIndex = 1;
//
// comboPLCType
//
this.comboPLCType.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
- this.comboPLCType.Font = new System.Drawing.Font("Microsoft Sans Serif", 14F);
+ this.comboPLCType.BackColor = System.Drawing.Color.WhiteSmoke;
+ this.comboPLCType.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.comboPLCType.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.comboPLCType.FormattingEnabled = true;
this.comboPLCType.Items.AddRange(new object[] {
"Production PLC",
"Scale PLC",
- "Simulation PLC",
+ "Simulated PLC",
"Test PLC"});
- this.comboPLCType.Location = new System.Drawing.Point(709, 527);
- this.comboPLCType.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2);
+ this.comboPLCType.Location = new System.Drawing.Point(5, 107);
+ this.comboPLCType.Margin = new System.Windows.Forms.Padding(2);
this.comboPLCType.Name = "comboPLCType";
- this.comboPLCType.Size = new System.Drawing.Size(203, 37);
+ this.comboPLCType.Size = new System.Drawing.Size(247, 28);
this.comboPLCType.TabIndex = 3;
- this.comboPLCType.Text = "Simulation PLC";
- //
- // ManualControl
- //
- this.ManualControl.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
- this.ManualControl.BackColor = System.Drawing.Color.LightGray;
- this.ManualControl.Enabled = false;
- this.ManualControl.Font = new System.Drawing.Font("Microsoft Sans Serif", 18F);
- this.ManualControl.Location = new System.Drawing.Point(1221, 39);
- this.ManualControl.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2);
- this.ManualControl.Name = "ManualControl";
- this.ManualControl.Size = new System.Drawing.Size(247, 89);
- this.ManualControl.TabIndex = 8;
- this.ManualControl.Text = "Manual Control";
- this.ManualControl.UseVisualStyleBackColor = false;
- this.ManualControl.Click += new System.EventHandler(this.ManualControl_Click);
+ this.comboPLCType.SelectedIndexChanged += new System.EventHandler(this.comboPLCType_SelectedIndexChanged);
//
// FreeControl
//
this.FreeControl.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.FreeControl.BackColor = System.Drawing.Color.LightGray;
this.FreeControl.Enabled = false;
+ this.FreeControl.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.FreeControl.Font = new System.Drawing.Font("Microsoft Sans Serif", 18F);
- this.FreeControl.Location = new System.Drawing.Point(944, 39);
- this.FreeControl.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2);
+ this.FreeControl.Location = new System.Drawing.Point(13, 15);
+ this.FreeControl.Margin = new System.Windows.Forms.Padding(2);
this.FreeControl.Name = "FreeControl";
- this.FreeControl.Size = new System.Drawing.Size(247, 89);
+ this.FreeControl.Size = new System.Drawing.Size(354, 44);
this.FreeControl.TabIndex = 9;
- this.FreeControl.Text = "Free Control";
+ this.FreeControl.Text = "Radio Telescope Control";
this.FreeControl.UseVisualStyleBackColor = false;
this.FreeControl.Click += new System.EventHandler(this.FreeControl_Click);
//
- // comboEncoderType
- //
- this.comboEncoderType.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
- this.comboEncoderType.Font = new System.Drawing.Font("Microsoft Sans Serif", 14F);
- this.comboEncoderType.FormattingEnabled = true;
- this.comboEncoderType.Items.AddRange(new object[] {
- "Production Absolute Encoder",
- "Simulated Absolute Encoder",
- "Test Absolute Encoder"});
- this.comboEncoderType.Location = new System.Drawing.Point(371, 590);
- this.comboEncoderType.Margin = new System.Windows.Forms.Padding(4);
- this.comboEncoderType.Name = "comboEncoderType";
- this.comboEncoderType.Size = new System.Drawing.Size(315, 37);
- this.comboEncoderType.TabIndex = 12;
- this.comboEncoderType.Text = "Simulated Absolute Encoder";
- //
- // comboMicrocontrollerBox
- //
- this.comboMicrocontrollerBox.Font = new System.Drawing.Font("Microsoft Sans Serif", 14F);
- this.comboMicrocontrollerBox.FormattingEnabled = true;
- this.comboMicrocontrollerBox.Items.AddRange(new object[] {
- "Production Microcontroller",
- "Simulated Microcontroller"});
- this.comboMicrocontrollerBox.Location = new System.Drawing.Point(371, 527);
- this.comboMicrocontrollerBox.Margin = new System.Windows.Forms.Padding(4);
- this.comboMicrocontrollerBox.Name = "comboMicrocontrollerBox";
- this.comboMicrocontrollerBox.Size = new System.Drawing.Size(315, 37);
- this.comboMicrocontrollerBox.TabIndex = 14;
- this.comboMicrocontrollerBox.Text = "Simulated Microcontroller";
+ // comboSensorNetworkBox
+ //
+ this.comboSensorNetworkBox.BackColor = System.Drawing.Color.WhiteSmoke;
+ this.comboSensorNetworkBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.comboSensorNetworkBox.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.comboSensorNetworkBox.FormattingEnabled = true;
+ this.comboSensorNetworkBox.Items.AddRange(new object[] {
+ "Production Sensor Network",
+ "Simulated Sensor Network"});
+ this.comboSensorNetworkBox.Location = new System.Drawing.Point(6, 17);
+ this.comboSensorNetworkBox.Name = "comboSensorNetworkBox";
+ this.comboSensorNetworkBox.Size = new System.Drawing.Size(246, 28);
+ this.comboSensorNetworkBox.TabIndex = 14;
+ this.comboSensorNetworkBox.SelectedIndexChanged += new System.EventHandler(this.comboSensorNetworkBox_SelectedIndexChanged);
//
// loopBackBox
//
- this.loopBackBox.AutoSize = true;
- this.loopBackBox.Location = new System.Drawing.Point(889, 585);
+ this.loopBackBox.Location = new System.Drawing.Point(539, 219);
+ this.loopBackBox.Margin = new System.Windows.Forms.Padding(2);
this.loopBackBox.Name = "loopBackBox";
- this.loopBackBox.Size = new System.Drawing.Size(124, 55);
- this.loopBackBox.TabIndex = 15;
- this.loopBackBox.Text = "Loop back \r\n(for simulation)\r\n ";
+ this.loopBackBox.Size = new System.Drawing.Size(160, 43);
+ this.loopBackBox.TabIndex = 28;
+ this.loopBackBox.Text = "Loop back (for simulation)";
this.loopBackBox.UseVisualStyleBackColor = true;
this.loopBackBox.CheckedChanged += new System.EventHandler(this.loopBackBox_CheckedChanged);
//
// LocalIPCombo
//
this.LocalIPCombo.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
- this.LocalIPCombo.Font = new System.Drawing.Font("Microsoft Sans Serif", 14F);
+ this.LocalIPCombo.BackColor = System.Drawing.Color.WhiteSmoke;
+ this.LocalIPCombo.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.LocalIPCombo.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.LocalIPCombo.FormattingEnabled = true;
- this.LocalIPCombo.Location = new System.Drawing.Point(709, 647);
- this.LocalIPCombo.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2);
+ this.LocalIPCombo.Items.AddRange(new object[] {
+ "RT IP Address",
+ "127.0.0.1"});
+ this.LocalIPCombo.Location = new System.Drawing.Point(6, 137);
+ this.LocalIPCombo.Margin = new System.Windows.Forms.Padding(2);
this.LocalIPCombo.Name = "LocalIPCombo";
- this.LocalIPCombo.Size = new System.Drawing.Size(263, 37);
+ this.LocalIPCombo.Size = new System.Drawing.Size(246, 28);
this.LocalIPCombo.TabIndex = 16;
- this.LocalIPCombo.Text = "this box IP";
//
// label1
//
this.label1.AutoSize = true;
- this.label1.Location = new System.Drawing.Point(12, 9);
+ this.label1.Location = new System.Drawing.Point(9, 7);
+ this.label1.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.label1.Name = "label1";
- this.label1.Size = new System.Drawing.Size(373, 17);
+ this.label1.Size = new System.Drawing.Size(271, 13);
this.label1.TabIndex = 17;
- this.label1.Text = "clik on the IP adress of the RT to open the diagnostic view";
+ this.label1.Text = "Click on the IP adress of the RT to open diagnostic form";
+ //
+ // simulationSettingsGroupbox
+ //
+ this.simulationSettingsGroupbox.BackColor = System.Drawing.Color.Gray;
+ this.simulationSettingsGroupbox.Controls.Add(this.label8);
+ this.simulationSettingsGroupbox.Controls.Add(this.txtSpectraPort);
+ this.simulationSettingsGroupbox.Controls.Add(this.comboWeatherStationBox);
+ this.simulationSettingsGroupbox.Controls.Add(this.LocalIPCombo);
+ this.simulationSettingsGroupbox.Controls.Add(this.comboSensorNetworkBox);
+ this.simulationSettingsGroupbox.Controls.Add(this.comboPLCType);
+ this.simulationSettingsGroupbox.Controls.Add(this.comboSpectraCyberBox);
+ this.simulationSettingsGroupbox.Controls.Add(this.label2);
+ this.simulationSettingsGroupbox.Controls.Add(this.RLLabel);
+ this.simulationSettingsGroupbox.Controls.Add(this.txtWSCOMPort);
+ this.simulationSettingsGroupbox.Controls.Add(this.txtRemoteListenerCOMPort);
+ this.simulationSettingsGroupbox.FlatStyle = System.Windows.Forms.FlatStyle.System;
+ this.simulationSettingsGroupbox.Location = new System.Drawing.Point(12, 258);
+ this.simulationSettingsGroupbox.Name = "simulationSettingsGroupbox";
+ this.simulationSettingsGroupbox.Size = new System.Drawing.Size(499, 170);
+ this.simulationSettingsGroupbox.TabIndex = 18;
+ this.simulationSettingsGroupbox.TabStop = false;
+ this.simulationSettingsGroupbox.Text = "Individual Component Simulation settings";
+ this.simulationSettingsGroupbox.Enter += new System.EventHandler(this.simulationSettingsGroupbox_Enter);
+ //
+ // label8
+ //
+ this.label8.AutoSize = true;
+ this.label8.Font = new System.Drawing.Font("Microsoft Sans Serif", 11.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.label8.Location = new System.Drawing.Point(257, 57);
+ this.label8.Name = "label8";
+ this.label8.Size = new System.Drawing.Size(120, 18);
+ this.label8.TabIndex = 23;
+ this.label8.Text = "Spectra Cyber:";
+ this.WCOMPortToolTip.SetToolTip(this.label8, "Enter a valid port number, between 1 and 65536");
+ //
+ // txtSpectraPort
+ //
+ this.txtSpectraPort.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+ this.txtSpectraPort.BackColor = System.Drawing.Color.Gainsboro;
+ this.txtSpectraPort.Font = new System.Drawing.Font("Microsoft Sans Serif", 14F);
+ this.txtSpectraPort.ForeColor = System.Drawing.Color.DarkGray;
+ this.txtSpectraPort.Location = new System.Drawing.Point(390, 18);
+ this.txtSpectraPort.Margin = new System.Windows.Forms.Padding(2);
+ this.txtSpectraPort.Name = "txtSpectraPort";
+ this.txtSpectraPort.Size = new System.Drawing.Size(104, 29);
+ this.txtSpectraPort.TabIndex = 24;
+ this.txtSpectraPort.Text = " COM port";
+ this.txtSpectraPort.TextChanged += new System.EventHandler(this.textBox1_TextChanged);
+ this.txtSpectraPort.Enter += new System.EventHandler(this.txtSpectraPort_Enter);
+ this.txtSpectraPort.Leave += new System.EventHandler(this.txtSpectraPort_Leave);
+ //
+ // label2
+ //
+ this.label2.AutoSize = true;
+ this.label2.Font = new System.Drawing.Font("Microsoft Sans Serif", 11.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.label2.Location = new System.Drawing.Point(257, 21);
+ this.label2.Name = "label2";
+ this.label2.Size = new System.Drawing.Size(132, 18);
+ this.label2.TabIndex = 17;
+ this.label2.Text = "Weather station:";
+ this.WCOMPortToolTip.SetToolTip(this.label2, "Enter a valid port number, between 1 and 65536");
+ this.label2.Click += new System.EventHandler(this.label2_MouseHover);
+ //
+ // RLLabel
+ //
+ this.RLLabel.AutoSize = true;
+ this.RLLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 11.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.RLLabel.Location = new System.Drawing.Point(257, 97);
+ this.RLLabel.Name = "RLLabel";
+ this.RLLabel.Size = new System.Drawing.Size(137, 18);
+ this.RLLabel.TabIndex = 17;
+ this.RLLabel.Text = "Remote Listener:";
+ this.RLPortToolTip.SetToolTip(this.RLLabel, "Enter a valid port number, between 1 and 65536");
+ //
+ // txtWSCOMPort
+ //
+ this.txtWSCOMPort.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+ this.txtWSCOMPort.BackColor = System.Drawing.Color.Gainsboro;
+ this.txtWSCOMPort.Font = new System.Drawing.Font("Microsoft Sans Serif", 14F);
+ this.txtWSCOMPort.ForeColor = System.Drawing.Color.DarkGray;
+ this.txtWSCOMPort.Location = new System.Drawing.Point(390, 54);
+ this.txtWSCOMPort.Margin = new System.Windows.Forms.Padding(2);
+ this.txtWSCOMPort.Name = "txtWSCOMPort";
+ this.txtWSCOMPort.Size = new System.Drawing.Size(104, 29);
+ this.txtWSCOMPort.TabIndex = 22;
+ this.txtWSCOMPort.Text = " COM port";
+ this.txtWSCOMPort.TextChanged += new System.EventHandler(this.txtWSCOMPort_TextChanged);
+ this.txtWSCOMPort.Enter += new System.EventHandler(this.txtWSCOMPort_Enter);
+ this.txtWSCOMPort.Leave += new System.EventHandler(this.txtWSCOMPort_Leave);
+ //
+ // txtRemoteListenerCOMPort
+ //
+ this.txtRemoteListenerCOMPort.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+ this.txtRemoteListenerCOMPort.BackColor = System.Drawing.Color.Gainsboro;
+ this.txtRemoteListenerCOMPort.Font = new System.Drawing.Font("Microsoft Sans Serif", 14F);
+ this.txtRemoteListenerCOMPort.ForeColor = System.Drawing.Color.DarkGray;
+ this.txtRemoteListenerCOMPort.Location = new System.Drawing.Point(390, 90);
+ this.txtRemoteListenerCOMPort.Margin = new System.Windows.Forms.Padding(2);
+ this.txtRemoteListenerCOMPort.Name = "txtRemoteListenerCOMPort";
+ this.txtRemoteListenerCOMPort.Size = new System.Drawing.Size(104, 29);
+ this.txtRemoteListenerCOMPort.TabIndex = 22;
+ this.txtRemoteListenerCOMPort.Text = "COM port";
+ this.txtRemoteListenerCOMPort.TextChanged += new System.EventHandler(this.txtRemoteListenerCOMPort_TextChanged);
+ this.txtRemoteListenerCOMPort.Enter += new System.EventHandler(this.txtRemoteListenerCOMPort_Enter);
+ this.txtRemoteListenerCOMPort.Leave += new System.EventHandler(this.txtRemoteListenerCOMPort_Leave);
+ //
+ // label3
+ //
+ this.label3.AutoSize = true;
+ this.label3.Font = new System.Drawing.Font("Microsoft Sans Serif", 11.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.label3.Location = new System.Drawing.Point(4, 56);
+ this.label3.Name = "label3";
+ this.label3.Size = new System.Drawing.Size(85, 18);
+ this.label3.TabIndex = 19;
+ this.label3.Text = " PLC port:";
+ this.PLCPortToolTip.SetToolTip(this.label3, "Enter a valid port number, between 1 and 65536");
+ this.label3.MouseHover += new System.EventHandler(this.label3_MouseHover);
+ //
+ // label4
+ //
+ this.label4.AutoSize = true;
+ this.label4.Font = new System.Drawing.Font("Microsoft Sans Serif", 11.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.label4.Location = new System.Drawing.Point(8, 23);
+ this.label4.Name = "label4";
+ this.label4.Size = new System.Drawing.Size(137, 18);
+ this.label4.TabIndex = 20;
+ this.label4.Text = "MCU IP Address:";
+ this.MCUIPToolTip.SetToolTip(this.label4, "Enter a valid IP Address (in the form xxx.xxx.xxx.xxx)");
+ this.label4.MouseHover += new System.EventHandler(this.label4_MouseHover);
+ //
+ // portGroupbox
+ //
+ this.portGroupbox.Controls.Add(this.label7);
+ this.portGroupbox.Controls.Add(this.label6);
+ this.portGroupbox.Controls.Add(this.sensorNetworkClientPort);
+ this.portGroupbox.Controls.Add(this.sensorNetworkClientIPAddress);
+ this.portGroupbox.Controls.Add(this.sensorNetworkServerPort);
+ this.portGroupbox.Controls.Add(this.sensorNetworkServerIPAddress);
+ this.portGroupbox.Controls.Add(this.txtMcuCOMPort);
+ this.portGroupbox.Controls.Add(this.label5);
+ this.portGroupbox.Controls.Add(this.txtPLCPort);
+ this.portGroupbox.Controls.Add(this.label4);
+ this.portGroupbox.Controls.Add(this.txtPLCIP);
+ this.portGroupbox.Controls.Add(this.label3);
+ this.portGroupbox.Location = new System.Drawing.Point(526, 25);
+ this.portGroupbox.Name = "portGroupbox";
+ this.portGroupbox.Size = new System.Drawing.Size(373, 195);
+ this.portGroupbox.TabIndex = 21;
+ this.portGroupbox.TabStop = false;
+ this.portGroupbox.Text = "System IP Address and Port Numbers";
+ this.portGroupbox.Enter += new System.EventHandler(this.portGroupbox_Enter);
+ //
+ // label7
+ //
+ this.label7.AutoSize = true;
+ this.label7.Font = new System.Drawing.Font("Microsoft Sans Serif", 11.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.label7.Location = new System.Drawing.Point(9, 162);
+ this.label7.Name = "label7";
+ this.label7.Size = new System.Drawing.Size(183, 18);
+ this.label7.TabIndex = 28;
+ this.label7.Text = "Sensor Network Client:";
+ this.WCOMPortToolTip.SetToolTip(this.label7, "Enter a valid port number, between 1 and 65536");
+ //
+ // label6
+ //
+ this.label6.AutoSize = true;
+ this.label6.Font = new System.Drawing.Font("Microsoft Sans Serif", 11.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.label6.Location = new System.Drawing.Point(9, 127);
+ this.label6.Name = "label6";
+ this.label6.Size = new System.Drawing.Size(183, 18);
+ this.label6.TabIndex = 27;
+ this.label6.Text = "Sensor Network Sever:";
+ this.WCOMPortToolTip.SetToolTip(this.label6, "Enter a valid port number, between 1 and 65536");
+ //
+ // sensorNetworkClientPort
+ //
+ this.sensorNetworkClientPort.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+ this.sensorNetworkClientPort.BackColor = System.Drawing.Color.Gainsboro;
+ this.sensorNetworkClientPort.Font = new System.Drawing.Font("Microsoft Sans Serif", 14F);
+ this.sensorNetworkClientPort.Location = new System.Drawing.Point(303, 157);
+ this.sensorNetworkClientPort.Margin = new System.Windows.Forms.Padding(2);
+ this.sensorNetworkClientPort.Name = "sensorNetworkClientPort";
+ this.sensorNetworkClientPort.Size = new System.Drawing.Size(64, 29);
+ this.sensorNetworkClientPort.TabIndex = 26;
+ this.sensorNetworkClientPort.TextChanged += new System.EventHandler(this.sensorNetworkClientPort_TextChanged);
+ this.sensorNetworkClientPort.Enter += new System.EventHandler(this.sensorNetworkClientPort_Enter);
+ this.sensorNetworkClientPort.Leave += new System.EventHandler(this.sensorNetworkClientPort_Leave);
+ //
+ // sensorNetworkClientIPAddress
+ //
+ this.sensorNetworkClientIPAddress.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+ this.sensorNetworkClientIPAddress.BackColor = System.Drawing.Color.Gainsboro;
+ this.sensorNetworkClientIPAddress.Font = new System.Drawing.Font("Microsoft Sans Serif", 14F);
+ this.sensorNetworkClientIPAddress.Location = new System.Drawing.Point(197, 157);
+ this.sensorNetworkClientIPAddress.Margin = new System.Windows.Forms.Padding(2);
+ this.sensorNetworkClientIPAddress.Name = "sensorNetworkClientIPAddress";
+ this.sensorNetworkClientIPAddress.Size = new System.Drawing.Size(104, 29);
+ this.sensorNetworkClientIPAddress.TabIndex = 25;
+ this.sensorNetworkClientIPAddress.TextChanged += new System.EventHandler(this.sensorNetworkClientIPAddress_TextChanged);
+ this.sensorNetworkClientIPAddress.Enter += new System.EventHandler(this.sensorNetworkClientIPAddress_Enter);
+ this.sensorNetworkClientIPAddress.Leave += new System.EventHandler(this.sensorNetworkClientIPAddress_Leave);
+ //
+ // sensorNetworkServerPort
+ //
+ this.sensorNetworkServerPort.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+ this.sensorNetworkServerPort.BackColor = System.Drawing.Color.Gainsboro;
+ this.sensorNetworkServerPort.Font = new System.Drawing.Font("Microsoft Sans Serif", 14F);
+ this.sensorNetworkServerPort.Location = new System.Drawing.Point(303, 121);
+ this.sensorNetworkServerPort.Margin = new System.Windows.Forms.Padding(2);
+ this.sensorNetworkServerPort.Name = "sensorNetworkServerPort";
+ this.sensorNetworkServerPort.Size = new System.Drawing.Size(64, 29);
+ this.sensorNetworkServerPort.TabIndex = 24;
+ this.sensorNetworkServerPort.TextChanged += new System.EventHandler(this.sensorNetworkServerPort_TextChanged);
+ this.sensorNetworkServerPort.Enter += new System.EventHandler(this.sensorNetworkServerPort_Enter);
+ this.sensorNetworkServerPort.Leave += new System.EventHandler(this.sensorNetworkServerPort_Leave);
+ //
+ // sensorNetworkServerIPAddress
+ //
+ this.sensorNetworkServerIPAddress.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+ this.sensorNetworkServerIPAddress.BackColor = System.Drawing.Color.Gainsboro;
+ this.sensorNetworkServerIPAddress.Font = new System.Drawing.Font("Microsoft Sans Serif", 14F);
+ this.sensorNetworkServerIPAddress.Location = new System.Drawing.Point(197, 121);
+ this.sensorNetworkServerIPAddress.Margin = new System.Windows.Forms.Padding(2);
+ this.sensorNetworkServerIPAddress.Name = "sensorNetworkServerIPAddress";
+ this.sensorNetworkServerIPAddress.Size = new System.Drawing.Size(104, 29);
+ this.sensorNetworkServerIPAddress.TabIndex = 23;
+ this.sensorNetworkServerIPAddress.TextChanged += new System.EventHandler(this.sensorNetworkServerIPAddress_TextChanged);
+ this.sensorNetworkServerIPAddress.Enter += new System.EventHandler(this.sensorNetworkServerIPAddress_Enter);
+ this.sensorNetworkServerIPAddress.Leave += new System.EventHandler(this.sensorNetworkServerIPAddress_Leave);
+ //
+ // txtMcuCOMPort
+ //
+ this.txtMcuCOMPort.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+ this.txtMcuCOMPort.BackColor = System.Drawing.Color.Gainsboro;
+ this.txtMcuCOMPort.Font = new System.Drawing.Font("Microsoft Sans Serif", 14F);
+ this.txtMcuCOMPort.Location = new System.Drawing.Point(249, 85);
+ this.txtMcuCOMPort.Margin = new System.Windows.Forms.Padding(2);
+ this.txtMcuCOMPort.Name = "txtMcuCOMPort";
+ this.txtMcuCOMPort.Size = new System.Drawing.Size(118, 29);
+ this.txtMcuCOMPort.TabIndex = 18;
+ this.txtMcuCOMPort.TextChanged += new System.EventHandler(this.txtMcuCOMPort_TextChanged);
+ //
+ // label5
+ //
+ this.label5.AutoSize = true;
+ this.label5.Font = new System.Drawing.Font("Microsoft Sans Serif", 11.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.label5.Location = new System.Drawing.Point(9, 93);
+ this.label5.Name = "label5";
+ this.label5.Size = new System.Drawing.Size(93, 18);
+ this.label5.TabIndex = 21;
+ this.label5.Text = "MCU Port: ";
+ this.MCUPortToolTip.SetToolTip(this.label5, "Enter a valid port number, between 1 and 65536");
+ this.label5.Click += new System.EventHandler(this.label5_MouseHover);
+ //
+ // acceptSettings
+ //
+ this.acceptSettings.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+ this.acceptSettings.BackColor = System.Drawing.Color.LightGray;
+ this.acceptSettings.Enabled = false;
+ this.acceptSettings.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+ this.acceptSettings.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.acceptSettings.Location = new System.Drawing.Point(539, 262);
+ this.acceptSettings.Margin = new System.Windows.Forms.Padding(2);
+ this.acceptSettings.Name = "acceptSettings";
+ this.acceptSettings.Size = new System.Drawing.Size(352, 51);
+ this.acceptSettings.TabIndex = 23;
+ this.acceptSettings.Text = "Finalize settings";
+ this.acceptSettings.UseVisualStyleBackColor = false;
+ this.acceptSettings.Click += new System.EventHandler(this.acceptSettings_Click);
+ //
+ // startRTGroupbox
+ //
+ this.startRTGroupbox.Controls.Add(this.FreeControl);
+ this.startRTGroupbox.Controls.Add(this.shutdownButton);
+ this.startRTGroupbox.Controls.Add(this.startButton);
+ this.startRTGroupbox.Location = new System.Drawing.Point(526, 315);
+ this.startRTGroupbox.Name = "startRTGroupbox";
+ this.startRTGroupbox.Size = new System.Drawing.Size(381, 113);
+ this.startRTGroupbox.TabIndex = 24;
+ this.startRTGroupbox.TabStop = false;
+ this.startRTGroupbox.Enter += new System.EventHandler(this.groupBox3_Enter);
+ //
+ // helpButton
+ //
+ this.helpButton.BackColor = System.Drawing.Color.Gainsboro;
+ this.helpButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
+ this.helpButton.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.helpButton.ForeColor = System.Drawing.SystemColors.Desktop;
+ this.helpButton.Location = new System.Drawing.Point(879, 2);
+ this.helpButton.Name = "helpButton";
+ this.helpButton.Size = new System.Drawing.Size(22, 24);
+ this.helpButton.TabIndex = 27;
+ this.helpButton.Text = "?";
+ this.helpButton.UseVisualStyleBackColor = false;
+ this.helpButton.Click += new System.EventHandler(this.helpButton_click);
+ //
+ // ProdcheckBox
+ //
+ this.ProdcheckBox.Location = new System.Drawing.Point(726, 225);
+ this.ProdcheckBox.Margin = new System.Windows.Forms.Padding(2);
+ this.ProdcheckBox.Name = "ProdcheckBox";
+ this.ProdcheckBox.Size = new System.Drawing.Size(175, 30);
+ this.ProdcheckBox.TabIndex = 28;
+ this.ProdcheckBox.Text = "Default Vals (for production)";
+ this.ProdcheckBox.UseVisualStyleBackColor = true;
+ this.ProdcheckBox.CheckedChanged += new System.EventHandler(this.ProdcheckBox_CheckedChanged);
+ //
+ // WCOMPortToolTip
+ //
+ this.WCOMPortToolTip.Popup += new System.Windows.Forms.PopupEventHandler(this.WCOMPortToolTip_Popup);
//
// MainForm
//
- this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
- this.ClientSize = new System.Drawing.Size(1483, 747);
+ this.BackColor = System.Drawing.Color.Gray;
+ this.ClientSize = new System.Drawing.Size(911, 432);
+ this.Controls.Add(this.helpButton);
+ this.Controls.Add(this.startRTGroupbox);
+ this.Controls.Add(this.acceptSettings);
+ this.Controls.Add(this.portGroupbox);
+ this.Controls.Add(this.simulationSettingsGroupbox);
this.Controls.Add(this.label1);
- this.Controls.Add(this.LocalIPCombo);
- this.Controls.Add(this.loopBackBox);
- this.Controls.Add(this.comboMicrocontrollerBox);
- this.Controls.Add(this.comboEncoderType);
- this.Controls.Add(this.FreeControl);
- this.Controls.Add(this.ManualControl);
- this.Controls.Add(this.comboPLCType);
- this.Controls.Add(this.checkBox1);
- this.Controls.Add(this.comboBox2);
- this.Controls.Add(this.txtPLCIP);
- this.Controls.Add(this.comboBox1);
- this.Controls.Add(this.txtPLCPort);
- this.Controls.Add(this.button2);
this.Controls.Add(this.dataGridView1);
- this.Controls.Add(this.button1);
- this.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2);
- this.MinimumSize = new System.Drawing.Size(1223, 441);
+ this.Controls.Add(this.loopBackBox);
+ this.Controls.Add(this.ProdcheckBox);
+ this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
+ this.Margin = new System.Windows.Forms.Padding(2);
+ this.MinimumSize = new System.Drawing.Size(920, 363);
this.Name = "MainForm";
this.Text = "MainForm";
this.Load += new System.EventHandler(this.MainForm_Load);
((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit();
+ this.simulationSettingsGroupbox.ResumeLayout(false);
+ this.simulationSettingsGroupbox.PerformLayout();
+ this.portGroupbox.ResumeLayout(false);
+ this.portGroupbox.PerformLayout();
+ this.startRTGroupbox.ResumeLayout(false);
this.ResumeLayout(false);
this.PerformLayout();
@@ -320,21 +617,81 @@ private void InitializeComponent()
#endregion
- private System.Windows.Forms.Button button1;
+ private System.Windows.Forms.Button startButton;
private System.Windows.Forms.DataGridView dataGridView1;
- private System.Windows.Forms.Button button2;
+ private System.Windows.Forms.Button shutdownButton;
private System.Windows.Forms.TextBox txtPLCPort;
- private System.Windows.Forms.ComboBox comboBox1;
+ private System.Windows.Forms.ComboBox comboSpectraCyberBox;
private System.Windows.Forms.TextBox txtPLCIP;
- private System.Windows.Forms.ComboBox comboBox2;
- private System.Windows.Forms.CheckBox checkBox1;
+ private System.Windows.Forms.ComboBox comboWeatherStationBox;
private System.Windows.Forms.ComboBox comboPLCType;
- private System.Windows.Forms.Button ManualControl;
private System.Windows.Forms.Button FreeControl;
- private System.Windows.Forms.ComboBox comboEncoderType;
- private System.Windows.Forms.ComboBox comboMicrocontrollerBox;
+ private System.Windows.Forms.ComboBox comboSensorNetworkBox;
private System.Windows.Forms.CheckBox loopBackBox;
private System.Windows.Forms.ComboBox LocalIPCombo;
private System.Windows.Forms.Label label1;
+ private System.Windows.Forms.GroupBox simulationSettingsGroupbox;
+ private System.Windows.Forms.Label label2;
+ private System.Windows.Forms.TextBox txtWSCOMPort;
+ private System.Windows.Forms.TextBox txtRemoteListenerCOMPort;
+ private System.Windows.Forms.Label RLLabel;
+ private System.Windows.Forms.Label label3;
+ private System.Windows.Forms.Label label4;
+ private System.Windows.Forms.GroupBox portGroupbox;
+ private System.Windows.Forms.TextBox txtMcuCOMPort;
+ private System.Windows.Forms.Label label5;
+ private System.Windows.Forms.Button acceptSettings;
+ private System.Windows.Forms.GroupBox startRTGroupbox;
+ private System.Windows.Forms.Button helpButton;
+ private System.Windows.Forms.CheckBox ProdcheckBox;
+ private System.Windows.Forms.ToolTip MCUIPToolTip;
+ private System.Windows.Forms.ToolTip MCUPortToolTip;
+ private System.Windows.Forms.ToolTip PLCPortToolTip;
+ private System.Windows.Forms.ToolTip WCOMPortToolTip;
+ private System.Windows.Forms.ToolTip RLPortToolTip;
+ private System.Windows.Forms.Label label7;
+ private System.Windows.Forms.Label label6;
+ private System.Windows.Forms.TextBox sensorNetworkClientPort;
+ private System.Windows.Forms.TextBox sensorNetworkClientIPAddress;
+ private System.Windows.Forms.TextBox sensorNetworkServerPort;
+ private System.Windows.Forms.TextBox sensorNetworkServerIPAddress;
+ private System.Windows.Forms.Label label8;
+ private System.Windows.Forms.TextBox txtSpectraPort;
+
+
+
+
+
+
+
+ //private void txtPLCPort_Validated(object sender, System.EventArgs e)
+ //{
+ // if (IsPLCPortValid()){
+ // txtPLCPortErrorProvider.SetError(this.txtPLCPort, string.Empty);
+ // }
+ // else
+ // {
+ // txtPLCPortErrorProvider.SetError(this.txtPLCPort, "PLC Port is required.");
+ // }
+ //}
+
+ //private bool IsPLCPortValid()
+ //{
+ // if((txtPLCPort.Text == "5012" || txtPLCPort.Text == "8080" || txtPLCPort.Text == "58006") && IsEmpty(txtPLCPort))
+ // {
+ // return true;
+ // }
+ // else
+ // {
+ // return false;
+ // }
+
+ //}
+
+ //private bool IsEmpty (System.Windows.Forms.TextBox text)
+ //{
+ // return (text.Text.Length == 0);
+ //}
+
}
}
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/GUI/MainForm.cs b/ControlRoomApplication/ControlRoomApplication/GUI/MainForm.cs
index afec8c0d..8f6db541 100644
--- a/ControlRoomApplication/ControlRoomApplication/GUI/MainForm.cs
+++ b/ControlRoomApplication/ControlRoomApplication/GUI/MainForm.cs
@@ -3,30 +3,57 @@
using ControlRoomApplication.GUI;
using ControlRoomApplication.Simulators.Hardware.WeatherStation;
using System;
+using System.IO;
using System.Collections.Generic;
using System.Threading;
using System.Windows.Forms;
+using System.Windows;
using ControlRoomApplication.Constants;
using ControlRoomApplication.Database;
using System.Net;
-using ControlRoomApplication.Controllers.BlkHeadUcontroler;
+using ControlRoomApplication.Entities.WeatherStation;
+using log4net.Appender;
+using ControlRoomApplication.Documentation;
+using ControlRoomApplication.Validation;
+using ControlRoomApplication.GUI.Data;
+using ControlRoomApplication.Util;
+using ControlRoomApplication.Controllers.SensorNetwork;
+using ControlRoomApplication.GUI.DropDownEnums;
+using System.Threading.Tasks;
namespace ControlRoomApplication.Main
{
- public partial class MainForm : Form
+ public partial class MainForm : Form, IAppender
{
private static int current_rt_id;
public List> AbstractRTDriverPairList { get; set; }
public List ProgramRTControllerList { get; set; }
public List ProgramPLCDriverList { get; set; }
public List ProgramControlRoomControllerList { get; set; }
- private ControlRoomController MainControlRoomController { get; set; }
- private Thread ControlRoomThread { get; set; }
- private Thread MicroctrlServerThread { get; set; }
- private CancellationTokenSource CancellationSource { get; set; }
+ public ControlRoomController MainControlRoomController { get; set; }
private static readonly log4net.ILog logger =
log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
+ public AbstractWeatherStation lastCreatedProductionWeatherStation = null;
+
+ public bool finalSettings = true;
+ public LoggerQueue log = new LoggerQueue();
+
+ // Booleans for user validation of input forms
+ public bool MCUIPValid = false;
+ public bool MCUPortValid = false;
+ public bool PLCPortValid = false;
+ public bool WCOMPortValid = false;
+ public bool RLPortValid = false;
+ public bool SpectraPortValid = false;
+ public bool SensorNetworkServerIPBool = false;
+ public bool SensorNetworkServerPortBool = false;
+ public bool SensorNetworkClientIPBool = false;
+ public bool SensorNetworkClientPortBool = false;
+
+ // form
+ RTControlFormData formData;
+
enum TempSensorType
{
Production,
@@ -41,20 +68,18 @@ enum MCUType
enum PLCType
{
- Production,
+ Production,
Scale,
Simulation,
Test
}
-
enum MicrocontrollerType
{
Production,
Simulation
}
-
///
/// Constructor for the main GUI form. Initializes the GUI form by calling the
@@ -69,21 +94,64 @@ public MainForm()
IPAddress[] v4_list = new IPAddress[ipHostInfo.AddressList.Length / 2];
System.Array.Copy(ipHostInfo.AddressList, ipHostInfo.AddressList.Length / 2, v4_list, 0, ipHostInfo.AddressList.Length / 2);
this.LocalIPCombo.Items.AddRange(v4_list);
-
-
- DatabaseOperations.DeleteLocalDatabase();
- logger.Info("<--------------- Control Room Application Started --------------->");
- dataGridView1.ColumnCount = 3;
+
+ logger.Info(Utilities.GetTimeStamp() + ": <--------------- Control Room Application Started --------------->");
+ dataGridView1.ColumnCount = 5;
dataGridView1.Columns[0].HeaderText = "ID";
dataGridView1.Columns[1].HeaderText = "PLC IP";
dataGridView1.Columns[2].HeaderText = "PLC Port";
+ dataGridView1.Columns[3].HeaderText = "MCU Port";
+ dataGridView1.Columns[4].HeaderText = "WS Port";
+ //dataGridView1.Columns[3].HeaderText = "MCU Port";
AbstractRTDriverPairList = new List>();
ProgramRTControllerList = new List();
ProgramPLCDriverList = new List();
ProgramControlRoomControllerList = new List();
current_rt_id = 0;
- logger.Info("MainForm Initalized");
+
+ // Initialize Button Settings
+ startRTGroupbox.BackColor = System.Drawing.Color.DarkGray;
+ acceptSettings.Enabled = false;
+ startButton.BackColor = System.Drawing.Color.Gainsboro;
+ startButton.Enabled = false;
+ shutdownButton.BackColor = System.Drawing.Color.Gainsboro;
+ shutdownButton.Enabled = false;
+ loopBackBox.Enabled = true;
+
+ comboSensorNetworkBox.SelectedIndex = (int)SensorNetworkDropdown.SimulatedSensorNetwork;
+ comboSpectraCyberBox.SelectedIndex = (int)SpectraCyberDropdown.SimulatedSpectraCyber;
+ comboWeatherStationBox.SelectedIndex = (int)WeatherStationDropdown.SimulatedWeatherStation;
+ comboPLCType.SelectedIndex = (int)PLCDropdown.SimulatedPLC;
+ LocalIPCombo.SelectedIndex = 0;
+
+ sensorNetworkServerIPAddress.Text = "IP Address";
+ // initialize formData struct
+ formData = new RTControlFormData();
+ sensorNetworkServerPort.Text = "Port";
+ sensorNetworkServerIPAddress.ForeColor = System.Drawing.Color.Gray;
+ sensorNetworkServerPort.ForeColor = System.Drawing.Color.Gray;
+ // initialize formData struct
+ formData = new RTControlFormData();
+
+ sensorNetworkClientIPAddress.Text = "IP Address";
+ sensorNetworkClientPort.Text = "Port";
+ sensorNetworkClientIPAddress.ForeColor = System.Drawing.Color.Gray;
+ sensorNetworkClientPort.ForeColor = System.Drawing.Color.Gray;
+
+ txtSpectraPort.Text = "COM";
+ txtSpectraPort.ForeColor = System.Drawing.Color.Gray;
+ txtWSCOMPort.Text = "COM";
+ txtWSCOMPort.ForeColor = System.Drawing.Color.Gray;
+ txtRemoteListenerCOMPort.Text = "COM";
+ txtRemoteListenerCOMPort.ForeColor = System.Drawing.Color.Gray;
+
+ logger.Info(Utilities.GetTimeStamp() + ": MainForm Initalized");
+ }
+
+ public void DoAppend(log4net.Core.LoggingEvent loggingEvent)
+ {
+ log.loggerQueue += loggingEvent.Level.Name + ": " + loggingEvent.MessageObject.ToString() + Environment.NewLine;
}
///
@@ -93,98 +161,259 @@ public MainForm()
///
/// Object specifying the sender of this Event.
/// The eventargs from the button being clicked on the GUI.
- private void button1_Click(object sender, EventArgs e)
- {
- logger.Info("Start Telescope Button Clicked");
- if (txtPLCPort.Text != null
- && txtPLCIP.Text != null
- && comboBox1.SelectedIndex > -1)
- {
- current_rt_id++;
- AbstractPLCDriver APLCDriver = BuildPLCDriver();
- AbstractMicrocontroller ctrler= build_CTRL();
- ctrler.BringUp();
- AbstractEncoderReader encoder= build_encoder( APLCDriver );
- RadioTelescope ARadioTelescope = BuildRT(APLCDriver, ctrler, encoder );
-
+ private void startButton_Click(object sender, EventArgs e)
+ {
+ logger.Info(Utilities.GetTimeStamp() + ": Start Telescope Button Clicked");
+
+ // This will tell us whether or not the RT is safe to start.
+ // It may not be safe to start if, for example, there are
+ // validation errors, or no Telescope is found in the DB
+ bool runRt = false;
- // Add the RT/PLC driver pair and the RT controller to their respective lists
- AbstractRTDriverPairList.Add(new KeyValuePair(ARadioTelescope, APLCDriver));
- ProgramRTControllerList.Add(new RadioTelescopeController(AbstractRTDriverPairList[current_rt_id - 1].Key));
- ProgramPLCDriverList.Add(APLCDriver);
+ // retrirve contents of JSON file
+ RadioTelescopeConfig RTConfig = RadioTelescopeConfig.DeserializeRTConfig();
- if (checkBox1.Checked)
+ // this will be null if an error occurs in parsing JSON from the file, if the expected types do not match, i.e. a string
+ // was given where an integer was expected, or if any of the inputs were null.
+ if (RTConfig == null)
+ {
+ DialogResult result = MessageBox.Show("An error occured while parsing the RTConfig JSON file. Would you like to recreate the JSON " +
+ "file?", "Error Parsing JSON", MessageBoxButtons.YesNo);
+ // If yes, recreate the file and remind the user to set the ID and change the flag back to false
+ if (result == DialogResult.Yes)
{
- logger.Info("Populating Local Database");
- DatabaseOperations.PopulateLocalDatabase(current_rt_id);
- Console.WriteLine(DatabaseOperations.GetNextAppointment(current_rt_id).StartTime.ToString());
- logger.Info("Disabling ManualControl and FreeControl");
- ManualControl.Enabled = false;
- FreeControl.Enabled = false;
+ RadioTelescopeConfig.CreateAndWriteToNewJSONFile(RadioTelescopeConfig.DEFAULT_JSON_CONTENTS);
+ MessageBox.Show("JSON file successfully recreated! Do not forget to specify the ID of telescope you want to run inside the file, " +
+ "and set the newTelescope flag to false.",
+ "JSON File Sucessfully Created", MessageBoxButtons.OK);
}
+ }
+ // retrieve RT by specified ID, if newTelescope flag set to false (meaning the user is trying to run a pre-existing telescope)
+ else if (!RTConfig.newTelescope)
+ {
+ RadioTelescope RT = DatabaseOperations.FetchRadioTelescopeByID(RTConfig.telescopeID);
+ if (RT == null)
+ {
+ DialogResult result = MessageBox.Show("The ID of " + RTConfig.telescopeID +
+ " was not found in the database. Would you like to create a new one?", "No Telescope found", MessageBoxButtons.YesNoCancel);
+ if (result == DialogResult.Yes)
+ {
+ runRt = true;
+ }
+ }
+ // we cannot run a second telescope if the selected one is already running.
+ else if (RT.online == 1)
+ {
+ DialogResult result = MessageBox.Show(
+ $"Telescope {RT.Id} is already in use, or the program crashed. Would you like to override this check and run the telescope anyway?",
+ "Telescope in use",
+ MessageBoxButtons.YesNo);
+
+ if (result == DialogResult.Yes)
+ {
+ runRt = true;
+ current_rt_id = RTConfig.telescopeID;
+ }
+ }
+ // else the telescope entered by the user is valid and is currently not running. Start it up
else
{
- logger.Info("Enabling ManualControl and FreeControl");
- ManualControl.Enabled = true;
- FreeControl.Enabled = true;
+ Console.WriteLine("The Selected RT with id " + RTConfig.telescopeID + " was not null, and is not running. Starting telescope " + RTConfig.telescopeID);
+ current_rt_id = RTConfig.telescopeID;
+ runRt = true;
}
- // If the main control room controller hasn't been initialized, initialize it.
- if (MainControlRoomController == null)
+ }
+ // else the user is trying to create a new telescope. Discard the RadioTelescope ID from the file, and ask
+ // the user to confirm they would like to create a new one.
+ else
+ {
+ DialogResult result = MessageBox.Show(
+ "The new telescope flag was set to true in the RTConfig File. Please confirm you like to create " +
+ "a new telescope, or go back and input the ID of an existing telescope in the database.",
+ "New Telescope Flag Set to True",
+ MessageBoxButtons.YesNoCancel);
+
+ if (result == DialogResult.Yes)
{
- logger.Info("Initializing ControlRoomController");
- MainControlRoomController = new ControlRoomController(new ControlRoom(BuildWeatherStation()));
+ runRt = true;
}
+ }
+
+ /** MCU IP VALIDATION **/
- // Start plc server and attempt to connect to it.
- logger.Info("Starting plc server and attempting to connect to it");
- ProgramPLCDriverList[current_rt_id - 1].StartAsyncAcceptingClients();
-//ProgramRTControllerList[current_rt_id - 1].RadioTelescope.PLCClient.ConnectToServer();//////####################################
+ // We want the IP to be marked as alive if we are running the simulation
+ // Otherwise, we call the validation
+ bool mcuIpAlive = true;
+ if (comboPLCType.SelectedIndex != 2)
+ {
+ mcuIpAlive = Validator.ServerRunningOnIp(txtPLCIP.Text, int.Parse(txtMcuCOMPort.Text));
+ }
+ else if (!txtPLCIP.Text.Contains("127.0.0."))
+ {
+ MessageBox.Show(
+ $"{txtPLCIP.Text} is not a valid IP address for the simulation MCU to run on.\n\n" +
+ $"Please make sure that the IP is a local host address (Ex: 127.0.0.xxx).",
- logger.Info("Adding RadioTelescope Controller");
- MainControlRoomController.AddRadioTelescopeController(ProgramRTControllerList[current_rt_id - 1]);
+ "Invalid Simulation MCU IP"
+ );
+ runRt = false;
+ }
- logger.Info("Starting Weather Monitoring Routine");
- MainControlRoomController.StartWeatherMonitoringRoutine();
+ // Verify that the MCU's IP address is alive
+ // This is skipped if we are simulating, since the server is run internally
+ if (!mcuIpAlive)
+ {
+ MessageBox.Show(
+ $"The MCU was not found on {txtPLCIP.Text}:{txtMcuCOMPort.Text}, or the system is still booting up.\n\n" +
+ $"If this problem persists, please power-cycle the PLC and MCU and verify all connections are firmly in place.",
- // Start RT controller's threaded management
- logger.Info("Starting RT controller's threaded management");
- RadioTelescopeControllerManagementThread ManagementThread = MainControlRoomController.ControlRoom.RTControllerManagementThreads[current_rt_id - 1];
- int RT_ID = ManagementThread.RadioTelescopeID;
- List AllAppointments = DatabaseOperations.GetListOfAppointmentsForRadioTelescope(RT_ID);
+ "MCU Not Found"
+ );
+ runRt = false;
+ }
- logger.Info("Attempting to queue " + AllAppointments.Count.ToString() + " appointments for RT with ID " + RT_ID.ToString());
- foreach (Appointment appt in AllAppointments)
- {
- logger.Info("\t[" + appt.Id + "] " + appt.StartTime.ToString() + " -> " + appt.EndTime.ToString());
- }
- if (ManagementThread.Start())
+ if (runRt)
+ {
+ shutdownButton.BackColor = System.Drawing.Color.Red;
+ shutdownButton.Enabled = true;
+ simulationSettingsGroupbox.BackColor = System.Drawing.Color.Gray;
+ comboSensorNetworkBox.Enabled = true;
+ comboWeatherStationBox.Enabled = true;
+ comboSpectraCyberBox.Enabled = true;
+ comboPLCType.Enabled = true;
+ LocalIPCombo.Enabled = true;
+
+ portGroupbox.BackColor = System.Drawing.Color.Gray;
+ txtPLCIP.Enabled = true;
+ txtMcuCOMPort.Enabled = true;
+ txtWSCOMPort.Enabled = true;
+ txtRemoteListenerCOMPort.Enabled = true;
+ txtPLCPort.Enabled = true;
+ txtSpectraPort.Enabled = true;
+
+ if (txtPLCPort.Text != null
+ && txtPLCIP.Text != null
+ && comboSpectraCyberBox.SelectedIndex > -1)
{
- logger.Info("Successfully started RT controller management thread [" + RT_ID.ToString() + "]");
- if (APLCDriver is ProductionPLCDriver)
+ // If the main control room controller hasn't been initialized, initialize it.
+ if (MainControlRoomController == null)
{
- ProgramRTControllerList[current_rt_id - 1].ConfigureRadioTelescope(500, 500, 0, 0);
+ logger.Info(Utilities.GetTimeStamp() + ": Initializing ControlRoomController");
+
+ int rlPort=0;
+ try
+ {
+ rlPort = Int32.Parse(txtRemoteListenerCOMPort.Text);
+ }catch(Exception ex)
+ {
+ logger.Error("There was an error parsing the Remote Listener port to an integer"+ex);
+
+ }
+ if (lastCreatedProductionWeatherStation == null)
+ MainControlRoomController = new ControlRoomController(new ControlRoom(BuildWeatherStation(), rlPort));
+ else
+ MainControlRoomController = new ControlRoomController(new ControlRoom(lastCreatedProductionWeatherStation, rlPort));
}
- }
- else
- {
- logger.Info("ERROR starting RT controller management thread [" + RT_ID.ToString() + "]" );
- }
- AddConfigurationToDataGrid();
+ bool isSensorNetworkServerSimulated = false;
+ if (comboSensorNetworkBox.SelectedIndex == (int)SensorNetworkDropdown.SimulatedSensorNetwork)
+ {
+ isSensorNetworkServerSimulated = true;
+ }
+
+ //current_rt_id++;
+ AbstractPLCDriver APLCDriver = BuildPLCDriver();
+ SensorNetworkServer sensorNetworkServer = new SensorNetworkServer(IPAddress.Parse(sensorNetworkServerIPAddress.Text), int.Parse(sensorNetworkServerPort.Text),
+ sensorNetworkClientIPAddress.Text, int.Parse(sensorNetworkClientPort.Text), RTConfig.telescopeID, isSensorNetworkServerSimulated);
+
+ sensorNetworkServer.StartSensorMonitoringRoutine();
+ RadioTelescope ARadioTelescope = BuildRT(APLCDriver, sensorNetworkServer);
+ ARadioTelescope.WeatherStation = MainControlRoomController.ControlRoom.WeatherStation;
+
+ // Add the RT/PLC driver pair and the RT controller to their respective lists
+ AbstractRTDriverPairList.Add(new KeyValuePair(ARadioTelescope, APLCDriver));
+ ProgramRTControllerList.Add(new RadioTelescopeController(AbstractRTDriverPairList[AbstractRTDriverPairList.Count - 1].Key));
+ ProgramPLCDriverList.Add(APLCDriver);
+
+ // Start plc server and attempt to connect to it.
+ logger.Info(Utilities.GetTimeStamp() + ": Starting plc server and attempting to connect to it");
+ ProgramPLCDriverList[ProgramPLCDriverList.Count - 1].StartAsyncAcceptingClients();
+ //ProgramRTControllerList[current_rt_id - 1].RadioTelescope.PLCClient.ConnectToServer();//////####################################
+
+ logger.Info(Utilities.GetTimeStamp() + ": Adding RadioTelescope Controller");
+ MainControlRoomController.AddRadioTelescopeController(ProgramRTControllerList[ProgramRTControllerList.Count - 1]);
+ ARadioTelescope.SetParent(ProgramRTControllerList[ProgramRTControllerList.Count - 1]);
+
+ // linking radio telescope controller to tcp listener
+ MainControlRoomController.ControlRoom.mobileControlServer.rtController = ARadioTelescope.GetParent();
+
+ logger.Info(Utilities.GetTimeStamp() + ": Starting Weather Monitoring Routine");
+ MainControlRoomController.StartWeatherMonitoringRoutine();
+
+ logger.Info(Utilities.GetTimeStamp() + ": Starting Spectra Cyber Controller");
+ ARadioTelescope.SpectraCyberController.BringUp();
+
+ logger.Info(Utilities.GetTimeStamp() + ": Setting Default Values for Spectra Cyber Controller");
+ ARadioTelescope.SpectraCyberController.SetSpectraCyberModeType(SpectraCyberModeTypeEnum.SPECTRAL);
+ ARadioTelescope.SpectraCyberController.SetSpectralIntegrationTime(SpectraCyberIntegrationTimeEnum.MID_TIME_SPAN);
+ ARadioTelescope.SpectraCyberController.SetContinuumOffsetVoltage(2.0);
+ // Start RT controller's threaded management
+ logger.Info(Utilities.GetTimeStamp() + ": Starting RT controller's threaded management");
+ RadioTelescopeControllerManagementThread ManagementThread = MainControlRoomController.ControlRoom.RTControllerManagementThreads[MainControlRoomController.ControlRoom.RTControllerManagementThreads.Count - 1];
- /*
- Console.WriteLine("at microtherad start");
- MicroctrlServerThread = new Thread(new ThreadStart(ControlRoomApplication.Controllers.BlkHeadUcontroler.MicroControlerControler.AsynchronousSocketListener.BringUp));
- MicroctrlServerThread.Start();
- //ControlRoomApplication.Controllers.BlkHeadUcontroler.MicroControlerControler.AsynchronousSocketListener.BringUp();
- */
+ // add telescope to database
+ //DatabaseOperations.AddRadioTelescope(ARadioTelescope);
+ int RT_ID = ManagementThread.RadioTelescopeID;
+ List AllAppointments = DatabaseOperations.GetListOfAppointmentsForRadioTelescope(RT_ID);
+ logger.Info(Utilities.GetTimeStamp() + ": Attempting to queue " + AllAppointments.Count.ToString() + " appointments for RT with ID " + RT_ID.ToString());
+ foreach (Appointment appt in AllAppointments)
+ {
+ logger.Info(Utilities.GetTimeStamp() + ": \t[" + appt.Id + "] " + appt.start_time.ToString() + " -> " + appt.end_time.ToString());
+ }
+
+ if (ManagementThread.Start())
+ {
+ logger.Info(Utilities.GetTimeStamp() + ": Successfully started RT controller management thread [" + RT_ID.ToString() + "]");
+
+ ProgramRTControllerList[ProgramRTControllerList.Count - 1].ConfigureRadioTelescope(.06, .06, 300, 300);
+ }
+ else
+ {
+ logger.Info(Utilities.GetTimeStamp() + ": ERROR starting RT controller management thread [" + RT_ID.ToString() + "]");
+ }
+
+ AddConfigurationToDataGrid();
+
+ // Set PLC override bits because they may be different than what's in the database
+ bool gateOvr = ProgramRTControllerList[ProgramRTControllerList.Count - 1].overrides.overrideGate;
+
+ APLCDriver.setregvalue((ushort)PLC_modbus_server_register_mapping.GATE_OVERRIDE, Convert.ToUInt16(gateOvr));
+
+ logger.Info(Utilities.GetTimeStamp() + ": Enabling ManualControl and FreeControl");
+ FreeControl.Enabled = true;
+
+ Task.Run(() =>
+ {
+ // Occasionally, during the initial connection (because things are being powered up, yet), there may be input errors present on the MCU.
+ // We aren't concerned with these errors, so clearing them is a part of the startup procedure.
+ Thread.Sleep(5000);
+ while (ProgramRTControllerList[ProgramRTControllerList.Count - 1].RadioTelescope.PLCDriver.CheckMCUErrors().Count > 0)
+ {
+ ProgramRTControllerList[ProgramRTControllerList.Count - 1].RadioTelescope.PLCDriver.ResetMCUErrors();
+ Thread.Sleep(3000);
+ }
+ });
+ }
}
+
+
+
}
///
@@ -192,8 +421,8 @@ private void button1_Click(object sender, EventArgs e)
///
private void AddConfigurationToDataGrid()
{
- logger.Info("Adding Configuration To DataGrid");
- string[] row = { (current_rt_id).ToString(), txtPLCIP.Text, txtPLCPort.Text };
+ logger.Info(Utilities.GetTimeStamp() + ": Adding Configuration To DataGrid");
+ string[] row = { (current_rt_id).ToString(), txtPLCIP.Text, txtPLCPort.Text, txtMcuCOMPort.Text, txtWSCOMPort.Text };
dataGridView1.Rows.Add(row);
dataGridView1.Update();
@@ -204,14 +433,14 @@ private void AddConfigurationToDataGrid()
///
private void button2_Click(object sender, EventArgs e)
{
- logger.Info("Shut Down Telescope Button Clicked");
+ logger.Info(Utilities.GetTimeStamp() + ": Shut Down Telescope Button Clicked");
if (MainControlRoomController != null && MainControlRoomController.RequestToKillWeatherMonitoringRoutine())
{
- logger.Info("Successfully shut down weather monitoring routine.");
+ logger.Info(Utilities.GetTimeStamp() + ": Successfully shut down weather monitoring routine.");
}
else
{
- logger.Info("ERROR shutting down weather monitoring routine!");
+ logger.Info(Utilities.GetTimeStamp() + ": ERROR shutting down weather monitoring routine!");
}
// Loop through the list of telescope controllers and call their respective bring down sequences.
@@ -219,39 +448,38 @@ private void button2_Click(object sender, EventArgs e)
{
if (MainControlRoomController.RemoveRadioTelescopeControllerAt(0, false))
{
- logger.Info("Successfully brought down RT controller at index " + i.ToString());
+ logger.Info(Utilities.GetTimeStamp() + ": Successfully brought down RT controller at index " + i.ToString());
}
else
{
- logger.Info("ERROR killing RT controller at index " + i.ToString());
+ logger.Info(Utilities.GetTimeStamp() + ": ERROR killing RT controller at index " + i.ToString());
}
- ProgramRTControllerList[0].RadioTelescope.SpectraCyberController.BringDown();
- ProgramRTControllerList[0].RadioTelescope.PLCDriver.Bring_down();
- ProgramPLCDriverList[0].RequestStopAsyncAcceptingClientsAndJoin();
+ //Turn off Telescope in database
+ ProgramRTControllerList[i].RadioTelescope.online = 0;
+ ProgramRTControllerList[i].RadioTelescope.SensorNetworkServer.EndSensorMonitoringRoutine();
+ DatabaseOperations.UpdateTelescope(ProgramRTControllerList[i].RadioTelescope);
+
+ ProgramRTControllerList[i].RadioTelescope.SpectraCyberController.BringDown();
+ ProgramRTControllerList[i].ShutdownRadioTelescope();
}
// End logging
- logger.Info("<--------------- Control Room Application Terminated --------------->");
+ logger.Info(Utilities.GetTimeStamp() + ": <--------------- Control Room Application Terminated --------------->");
Environment.Exit(0);
}
- ///
- /// Erases the current text in the plc port textbox.
- ///
- private void textBox2_Focus(object sender, EventArgs e)
+ protected override void OnFormClosed(FormClosedEventArgs e)
{
- logger.Info("textBox2_Focus Event");
- txtPLCIP.Text = "";
- }
+ for (int i = 0; i < ProgramRTControllerList.Count; i++)
+ {
+ //Turn off Telescope in database
+ ProgramRTControllerList[i].RadioTelescope.online = 0;
+ ProgramRTControllerList[i].RadioTelescope.SensorNetworkServer.EndSensorMonitoringRoutine();
+ DatabaseOperations.UpdateTelescope(ProgramRTControllerList[i].RadioTelescope);
+ ProgramRTControllerList[i].ShutdownRadioTelescope();
+ }
- ///
- /// Erases the current text in the plc IP address textbox.
- ///
- private void textBox1_Focus(object sender, EventArgs e)
- {
- logger.Info("textBox1_Focus Event");
- txtPLCPort.Text = "";
}
///
@@ -260,11 +488,14 @@ private void textBox1_Focus(object sender, EventArgs e)
///
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
- logger.Info("dataGridView1_CellContent Clicked");
- try {
- DiagnosticsForm diagnosticForm = new DiagnosticsForm( MainControlRoomController.ControlRoom , dataGridView1.CurrentCell.RowIndex );
+ logger.Info(Utilities.GetTimeStamp() + ": dataGridView1_CellContent Clicked");
+ try
+ {
+ DiagnosticsForm diagnosticForm = new DiagnosticsForm(MainControlRoomController.ControlRoom, AbstractRTDriverPairList[dataGridView1.CurrentCell.RowIndex].Key.Id, this);
diagnosticForm.Show();
- } catch {
+ }
+ catch
+ {
}
}
@@ -273,20 +504,68 @@ private void dataGridView1_CellContentClick(object sender, DataGridViewCellEvent
/// Builds a radio telescope instance based off of the input from the GUI form.
///
/// A radio telescope instance representing the configuration chosen.
- public RadioTelescope BuildRT(AbstractPLCDriver abstractPLCDriver , AbstractMicrocontroller ctrler , AbstractEncoderReader encoder )
+ public RadioTelescope BuildRT(AbstractPLCDriver abstractPLCDriver, SensorNetworkServer sns)
{
- logger.Info("Building RadioTelescope");
+ logger.Info(Utilities.GetTimeStamp() + ": Building RadioTelescope");
+
+ // if this is set to 0, it has not been updated with an existing ID from the database. Therefore, we must create one.
+ if (current_rt_id == 0)
+ {
+ RadioTelescope newRT = new RadioTelescope();
+ newRT.Location = new Location(0, 0, 0, "");
+ newRT.CalibrationOrientation = new Entities.Orientation(0, 0);
+ newRT.CurrentOrientation = new Entities.Orientation(0, 0);
+
+ // This is the TELESCOPE TYPE
+ // It is now set to SLIP_RING because we finally removed the hard stops. Isn't that exciting?!
+ newRT._TeleType = RadioTelescopeTypeEnum.SLIP_RING;
+
+ DatabaseOperations.AddRadioTelescope(newRT);
+
+ newRT.Id = DatabaseOperations.FetchLastRadioTelescope().Id;
+
+ // Set software stops
+ newRT.maxElevationDegrees = MiscellaneousConstants.MAX_SOFTWARE_STOP_EL_DEGREES;
+ newRT.minElevationDegrees = MiscellaneousConstants.MIN_SOFTWARE_STOP_EL_DEGREES;
+
+ //Turn telescope on in database
+ newRT.online = 1;
+ DatabaseOperations.UpdateTelescope(newRT);
+
+ // These settings are not stored in the database, so they are new every time
+ newRT.PLCDriver = abstractPLCDriver;
+ newRT.PLCDriver.setTelescopeType(newRT._TeleType);
+ newRT.SpectraCyberController = BuildSpectraCyber();
+ newRT.SensorNetworkServer = sns;
+ logger.Info(Utilities.GetTimeStamp() + ": New RadioTelescope built successfully");
+
+ current_rt_id = newRT.Id;
+
+ // update the JSON config file to reflect the newly created telescope
+ RadioTelescopeConfig.SerializeRTConfig(new RadioTelescopeConfig(newRT.Id, false));
+
+ return newRT;
+ }
+ else
+ // else there has been a specified RT instance we are retrieving from the database. Do that and build that specific telescope here
+ {
+ RadioTelescope existingRT = DatabaseOperations.FetchRadioTelescopeByID(current_rt_id);
- // PLCClientCommunicationHandler PLCCommsHandler = new PLCClientCommunicationHandler(txtPLCIP.Text, int.Parse(txtPLCPort.Text));///###############################
+ // Turn on telescope in database
+ existingRT.online = 1;
+ DatabaseOperations.UpdateTelescope(existingRT);
- // Create Radio Telescope Location
- Location location = MiscellaneousConstants.JOHN_RUDY_PARK;
+ // These settings are not stored in the database, so they are new every time
+ existingRT.PLCDriver = abstractPLCDriver;
+ existingRT.PLCDriver.setTelescopeType(existingRT._TeleType);
+ existingRT.SpectraCyberController = BuildSpectraCyber();
+ existingRT.SensorNetworkServer = sns;
+ logger.Info(Utilities.GetTimeStamp() + ": Existing RadioTelescope with ID " + current_rt_id + " retrieved and built successfully");
- // Return Radio Telescope
- RadioTelescope rt = new RadioTelescope(BuildSpectraCyber(), abstractPLCDriver, location, new Entities.Orientation(0,90), current_rt_id, ctrler, encoder );
+ return existingRT;
+
+ }
- logger.Info("RadioTelescope Built Successfully");
- return rt;
}
///
@@ -295,16 +574,16 @@ public RadioTelescope BuildRT(AbstractPLCDriver abstractPLCDriver , AbstractMicr
/// A spectracyber instance based off of the configuration specified by the GUI.
public AbstractSpectraCyberController BuildSpectraCyber()
{
- switch (comboBox1.SelectedIndex)
+ switch (comboSpectraCyberBox.SelectedIndex)
{
case 0:
- logger.Info("Building SpectraCyber");
- return new SpectraCyberController(new SpectraCyber());
+ logger.Info(Utilities.GetTimeStamp() + ": Building SpectraCyber");
+ return new SpectraCyberController(new SpectraCyber("COM" + txtSpectraPort.Text));
case 1:
default:
- logger.Info("Building SpectraCyberSimulator");
- return new SpectraCyberTestController(new SpectraCyberSimulator());
+ logger.Info(Utilities.GetTimeStamp() + ": Building SpectraCyberSimulator");
+ return new SpectraCyberSimulatorController(new SpectraCyberSimulator());
}
}
@@ -317,89 +596,48 @@ public AbstractPLCDriver BuildPLCDriver()
switch (comboPLCType.SelectedIndex)
{
case 0:
- logger.Info("Building ProductionPLCDriver");
- return new ProductionMCUDriver(LocalIPCombo.Text, txtPLCIP.Text, int.Parse(txtPLCPort.Text), int.Parse(txtPLCPort.Text));
+ logger.Info(Utilities.GetTimeStamp() + ": Building ProductionPLCDriver");
+ return new ProductionPLCDriver(LocalIPCombo.Text, txtPLCIP.Text, int.Parse(txtMcuCOMPort.Text), int.Parse(txtPLCPort.Text));
case 1:
- logger.Info("Building ScaleModelPLCDriver");
- return new ScaleModelPLCDriver(LocalIPCombo.Text, txtPLCIP.Text, int.Parse(txtPLCPort.Text), int.Parse(txtPLCPort.Text));
+ logger.Info(Utilities.GetTimeStamp() + ": Building ScaleModelPLCDriver");
+ return new ScaleModelPLCDriver(LocalIPCombo.Text, txtPLCIP.Text, int.Parse(txtMcuCOMPort.Text), int.Parse(txtPLCPort.Text));
case 3:
- logger.Info("Building TestPLCDriver");
- return new TestPLCDriver(LocalIPCombo.Text, txtPLCIP.Text, int.Parse(txtPLCPort.Text), int.Parse(txtPLCPort.Text));
-
+ logger.Info(Utilities.GetTimeStamp() + ": Building TestPLCDriver");
+ return new TestPLCDriver(LocalIPCombo.Text, txtPLCIP.Text, int.Parse(txtMcuCOMPort.Text), int.Parse(txtPLCPort.Text), false);
case 2:
default:
- logger.Info("Building SimulationPLCDriver");
- return new SimulationPLCDriver(LocalIPCombo.Text, txtPLCIP.Text, int.Parse(txtPLCPort.Text), int.Parse(txtPLCPort.Text));
- }
- }
-
- public AbstractEncoderReader build_encoder( AbstractPLCDriver plc ) {
- return new SimulatedEncoder(plc , LocalIPCombo.Text , 1602 );
- }
-
- public AbstractMicrocontroller build_CTRL() {
- switch(comboMicrocontrollerBox.SelectedIndex) {
- case 0:
- logger.Info( "Building ProductionPLCDriver" );
- return new MicroControlerControler( LocalIPCombo.Text , 1600);
-
- case 1:
- logger.Info( "Building ScaleModelPLCDriver" );
- return new SimulatedMicrocontroller( -20,100 );
-
- default:
- logger.Info( "Building SimulationPLCDriver" );
- return new SimulatedMicrocontroller( -20,100);
+ logger.Info(Utilities.GetTimeStamp() + ": Building SimulationPLCDriver");
+ return new SimulationPLCDriver(LocalIPCombo.Text, txtPLCIP.Text, int.Parse(txtMcuCOMPort.Text), int.Parse(txtPLCPort.Text), false, false);
}
}
- ///
- ///
- ///
- ///
- public bool IsMicrocontrollerSimulated()
- {
- bool isSimulated = false;
-
- logger.Info("Selected Microcontroller Type: ");
-
- if (comboMicrocontrollerBox.SelectedIndex == (int)MicrocontrollerType.Production)
- {
- isSimulated = false;
- }
- else
- {
- isSimulated = true;
- }
-
- return isSimulated;
- }
-
-
-
-
-
///
/// Build a weather station based off of the input from the GUI form.
///
/// A weather station instance based off of the configuration specified.
public AbstractWeatherStation BuildWeatherStation()
{
- switch (comboBox2.SelectedIndex)
+ switch (comboWeatherStationBox.SelectedIndex)
{
case 0:
- logger.Error("The production weather station is not yet supported.");
- throw new NotImplementedException("The production weather station is not yet supported.");
-
+ logger.Info(Utilities.GetTimeStamp() + ": Building ProductionWeatherStation");
+ try
+ {
+ return new WeatherStation(1000, int.Parse(txtWSCOMPort.Text));
+ }catch(Exception e)
+ {
+ return null;
+ }
+
case 2:
- logger.Error("The test weather station is not yet supported.");
+ logger.Error(Utilities.GetTimeStamp() + ": The test weather station is not yet supported.");
throw new NotImplementedException("The test weather station is not yet supported.");
case 1:
default:
- logger.Info("Building SimulationWeatherStation");
+ logger.Info(Utilities.GetTimeStamp() + ": Building SimulationWeatherStation");
return new SimulationWeatherStation(1000);
}
}
@@ -411,8 +649,9 @@ public AbstractWeatherStation BuildWeatherStation()
///
private void FreeControl_Click(object sender, EventArgs e)
{
- logger.Info("Free Control Button Clicked");
- FreeControlForm freeControlWindow = new FreeControlForm(MainControlRoomController.ControlRoom, current_rt_id);
+ logger.Info(Utilities.GetTimeStamp() + ": Free Control Button Clicked");
+ int rtIDforControl = AbstractRTDriverPairList[dataGridView1.CurrentCell.RowIndex].Key.Id;
+ FreeControlForm freeControlWindow = new FreeControlForm(MainControlRoomController.ControlRoom, rtIDforControl, formData);
// Create free control thread
Thread FreeControlThread = new Thread(() => freeControlWindow.ShowDialog())
{
@@ -425,17 +664,18 @@ private void FreeControl_Click(object sender, EventArgs e)
/// Generates a manual control form that allows manual control access to a radio telescope
/// instance through the generated form.
///
- private void ManualControl_Click(object sender, EventArgs e)
- {
- logger.Info("Manual Control Button Clicked");
- ManualControlForm manualControlWindow = new ManualControlForm(MainControlRoomController.ControlRoom, current_rt_id);
- // Create free control thread
- Thread ManualControlThread = new Thread(() => manualControlWindow.ShowDialog())
- {
- Name = "Manual Control Thread"
- };
- ManualControlThread.Start();
- }
+ //private void ManualControl_Click(object sender, EventArgs e)
+ //{
+ // logger.Info(Utilities.GetTimeStamp() + ": Manual Control Button Clicked");
+ // ProgramRTControllerList[current_rt_id - 1].ConfigureRadioTelescope( .1 , .1 , 0 , 0 );
+ // ManualControlForm manualControlWindow = new ManualControlForm(MainControlRoomController.ControlRoom, current_rt_id);
+ // // Create free control thread
+ // Thread ManualControlThread = new Thread(() => manualControlWindow.ShowDialog())
+ // {
+ // Name = "Manual Control Thread"
+ // };
+ // ManualControlThread.Start();
+ //}
private void MainForm_Load(object sender, EventArgs e)
{
@@ -444,16 +684,693 @@ private void MainForm_Load(object sender, EventArgs e)
private void loopBackBox_CheckedChanged(object sender, EventArgs e)
{
+
if (loopBackBox.Checked)
{
- this.txtPLCIP.Text = "127.0.0.1";
+ ProdcheckBox.Checked = false;
+ this.txtWSCOMPort.Text = "222"; //default WS COM port # is 221
+ this.txtSpectraPort.Text = "777";
+ this.txtRemoteListenerCOMPort.Text = "80";
+ this.txtMcuCOMPort.Text = ((int)(8083 + ProgramPLCDriverList.Count * 3)).ToString(); ; //default MCU Port
+ this.txtPLCIP.Text = "127.0.0.1";//default IP address
+
+ this.sensorNetworkServerIPAddress.Text = "127.0.0.1";
+ this.sensorNetworkClientIPAddress.Text = "127.0.0.1";
+ this.sensorNetworkServerIPAddress.ForeColor = System.Drawing.Color.Black;
+ this.sensorNetworkClientIPAddress.ForeColor = System.Drawing.Color.Black;
+
+ this.sensorNetworkServerPort.Text = "1600";
+ this.sensorNetworkClientPort.Text = "1680";
+ this.sensorNetworkServerPort.ForeColor = System.Drawing.Color.Black;
+ this.sensorNetworkClientPort.ForeColor = System.Drawing.Color.Black;
+
+ comboSensorNetworkBox.SelectedIndex = (int)SensorNetworkDropdown.SimulatedSensorNetwork;
+ comboSpectraCyberBox.SelectedIndex = (int)SpectraCyberDropdown.SimulatedSpectraCyber;
+ comboWeatherStationBox.SelectedIndex = (int)WeatherStationDropdown.SimulatedWeatherStation;
+ comboPLCType.SelectedIndex = (int)PLCType.Simulation;
+
if (LocalIPCombo.FindStringExact("127.0.0.1") == -1)
{
this.LocalIPCombo.Items.Add(IPAddress.Parse("127.0.0.1"));
}
this.LocalIPCombo.SelectedIndex = LocalIPCombo.FindStringExact("127.0.0.1");
}
- this.txtPLCPort.Text = ((int)(8080+ ProgramPLCDriverList.Count*3)).ToString();
+ this.txtPLCPort.Text = ((int)(8082 + ProgramPLCDriverList.Count * 3)).ToString();
+
+ }
+
+ private void ProdcheckBox_CheckedChanged(object sender, EventArgs e)
+ {
+ if (ProdcheckBox.Checked)
+ {
+ loopBackBox.Checked = false;
+ this.txtWSCOMPort.Text = "222"; //default WS COM port # is 221
+ this.txtSpectraPort.Text = "777";
+ this.txtMcuCOMPort.Text = "502"; //default MCU Port
+ this.txtPLCIP.Text = "192.168.0.50";//default IP address
+ this.txtRemoteListenerCOMPort.Text = "80";
+ this.comboPLCType.SelectedIndex = (int)PLCDropdown.ProductionPLC;
+ if (LocalIPCombo.FindStringExact("192.168.0.70") == -1)
+ {
+ this.LocalIPCombo.Items.Add(IPAddress.Parse("192.168.0.70"));
+ }
+ this.LocalIPCombo.SelectedIndex = LocalIPCombo.FindStringExact("192.168.0.70");
+ this.txtPLCPort.Text = "502";
+ comboSensorNetworkBox.SelectedIndex = (int)SensorNetworkDropdown.ProductionSensorNetwork;
+ comboSpectraCyberBox.SelectedIndex = (int)SpectraCyberDropdown.ProductionSpectraCyber;
+ comboWeatherStationBox.SelectedIndex = (int)WeatherStationDropdown.ProductionWeatherStation;
+
+ // SensorNetwork and Server IP/Ports
+
+ this.sensorNetworkServerIPAddress.Text = "192.168.0.10";
+ this.sensorNetworkClientIPAddress.Text = "192.168.0.197";
+ this.sensorNetworkServerIPAddress.ForeColor = System.Drawing.Color.Black;
+ this.sensorNetworkClientIPAddress.ForeColor = System.Drawing.Color.Black;
+
+ this.sensorNetworkServerPort.Text = "1600";
+ this.sensorNetworkClientPort.Text = "1680";
+ this.sensorNetworkServerPort.ForeColor = System.Drawing.Color.Black;
+ this.sensorNetworkClientPort.ForeColor = System.Drawing.Color.Black;
+ }
+ }
+
+ private void comboSensorNetworkBox_SelectedIndexChanged(object sender, EventArgs e)
+ {
+ if (comboSensorNetworkBox.SelectedIndex == (int)SensorNetworkDropdown.ProductionSensorNetwork)
+ {
+ this.sensorNetworkServerIPAddress.Text = "192.168.0.10";
+ this.sensorNetworkClientIPAddress.Text = "192.168.0.197";
+ this.sensorNetworkServerIPAddress.ForeColor = System.Drawing.Color.Black;
+ this.sensorNetworkClientIPAddress.ForeColor = System.Drawing.Color.Black;
+
+ this.sensorNetworkServerPort.Text = "1600";
+ this.sensorNetworkClientPort.Text = "1680";
+ this.sensorNetworkServerPort.ForeColor = System.Drawing.Color.Black;
+ this.sensorNetworkClientPort.ForeColor = System.Drawing.Color.Black;
+ }
+ else
+ {
+ this.sensorNetworkServerIPAddress.Text = "127.0.0.1";
+ this.sensorNetworkClientIPAddress.Text = "127.0.0.1";
+ this.sensorNetworkServerIPAddress.ForeColor = System.Drawing.Color.Black;
+ this.sensorNetworkClientIPAddress.ForeColor = System.Drawing.Color.Black;
+
+ this.sensorNetworkServerPort.Text = "1600";
+ this.sensorNetworkClientPort.Text = "1680";
+ this.sensorNetworkServerPort.ForeColor = System.Drawing.Color.Black;
+ this.sensorNetworkClientPort.ForeColor = System.Drawing.Color.Black;
+ }
+ }
+
+ private void txtPLCPort_TextChanged(object sender, EventArgs e)
+ {
+ PLCPortValid = Validator.ValidatePort(txtPLCPort.Text);
+ if (!PLCPortValid)
+ {
+ acceptSettings.Enabled = false;
+ txtPLCPort.BackColor = System.Drawing.Color.Yellow;
+ this.PLCPortToolTip.Show("Enter a valid port number\n" +
+ " between 1 and 65536", label3);
+ }
+ else
+ {
+ txtPLCPort.BackColor = System.Drawing.Color.White;
+ this.PLCPortToolTip.Hide(label3);
+ }
+ if (RLPortValid && PLCPortValid && MCUPortValid && MCUIPValid && WCOMPortValid && SensorNetworkServerIPBool && SensorNetworkServerPortBool && SensorNetworkClientIPBool && SensorNetworkClientPortBool)
+ {
+ acceptSettings.Enabled = true;
+ }
+
+ }
+
+ private void txtPLCIP_TextChanged(object sender, EventArgs e)
+ {
+ MCUIPValid = Validator.ValidateIPAddress(txtPLCIP.Text);
+ if (!MCUIPValid)
+ {
+ acceptSettings.Enabled = false;
+ txtPLCIP.BackColor = System.Drawing.Color.Yellow;
+ this.MCUIPToolTip.Show("Enter a valid IP Address\n" +
+ " (xxx.xxx.xxx.xxx)", label4);
+ }
+ else
+ {
+ txtPLCIP.BackColor = System.Drawing.Color.White;
+ this.MCUIPToolTip.Hide(label4);
+ }
+ if (RLPortValid && PLCPortValid && MCUPortValid && MCUIPValid && WCOMPortValid && SensorNetworkServerIPBool && SensorNetworkServerPortBool && SensorNetworkClientIPBool && SensorNetworkClientPortBool)
+ {
+ acceptSettings.Enabled = true;
+ }
+ }
+
+ private void label2_MouseHover(object sender, EventArgs e)
+ {
+ //this.WCOMPortToolTip.Show("Enter a valid port number, between 1 and 65536", label2);
+ }
+ private void label3_MouseHover(object sender, EventArgs e)
+ {
+ //this.PLCPortToolTip.Show("Enter a valid port number, between 1 and 65536", label3);
+ }
+
+ private void label4_MouseHover(object sender, EventArgs e)
+ {
+ //this.MCUIPToolTip.Show("Enter a valid IP Address (xxx.xxx.xxx.xxx)", label4);
+ }
+
+ private void label5_MouseHover(object sender, EventArgs e)
+ {
+ //this.MCUPortToolTip.Show("Enter a valid port number, between 1 and 65536", label5);
+ }
+
+ private void txtWSCOMPort_TextChanged(object sender, EventArgs e)
+ {
+
+ if (txtWSCOMPort.Text != "COM")
+ {
+ WCOMPortValid = Validator.ValidatePort(txtWSCOMPort.Text);
+ if (!WCOMPortValid)
+ {
+ acceptSettings.Enabled = false;
+ txtWSCOMPort.BackColor = System.Drawing.Color.Yellow;
+ this.WCOMPortToolTip.Show("Enter a valid port number\n" +
+ " between 1 and 65536", label2);
+ }
+ else
+ {
+ txtWSCOMPort.BackColor = System.Drawing.Color.White;
+ this.WCOMPortToolTip.Hide(label2);
+
+ }
+ if (RLPortValid && PLCPortValid && MCUPortValid && MCUIPValid && WCOMPortValid && SensorNetworkServerIPBool && SensorNetworkServerPortBool && SensorNetworkClientIPBool && SensorNetworkClientPortBool)
+ {
+ acceptSettings.Enabled = true;
+ }
+
+ }
+ else
+ {
+ txtWSCOMPort.BackColor = System.Drawing.Color.LightGray;
+ this.WCOMPortToolTip.Hide(label2);
+ }
+ }
+
+ private void txtRemoteListenerCOMPort_TextChanged(object sender, EventArgs e)
+ {
+
+ if (txtRemoteListenerCOMPort.Text != "COM")
+ {
+ RLPortValid = Validator.ValidatePort(txtRemoteListenerCOMPort.Text);
+ if (!RLPortValid)
+ {
+ acceptSettings.Enabled = false;
+ txtRemoteListenerCOMPort.BackColor = System.Drawing.Color.Yellow;
+ this.RLPortToolTip.Show("Enter a valid port number\n" +" between 1 and 65536", RLLabel);
+ }
+ else
+ {
+ txtRemoteListenerCOMPort.BackColor = System.Drawing.Color.White;
+ this.RLPortToolTip.Hide(RLLabel);
+
+ }
+ if (RLPortValid && PLCPortValid && MCUPortValid && MCUIPValid && WCOMPortValid && SensorNetworkServerIPBool && SensorNetworkServerPortBool && SensorNetworkClientIPBool && SensorNetworkClientPortBool)
+ {
+ acceptSettings.Enabled = true;
+ }
+
+ }
+ else
+ {
+ txtRemoteListenerCOMPort.BackColor = System.Drawing.Color.LightGray;
+ this.RLPortToolTip.Hide(RLLabel);
+ }
+ }
+
+ private void groupBox3_Enter(object sender, EventArgs e)
+ {
+
+ }
+
+ private void acceptSettings_Click(object sender, EventArgs e)
+ {
+ finalSettings = !finalSettings;
+
+ if (finalSettings == false)
+ {
+ if (comboWeatherStationBox.Text == "Production Weather Station")
+ {
+ lastCreatedProductionWeatherStation = BuildWeatherStation();
+
+ if (lastCreatedProductionWeatherStation != null)
+ {
+ startButton.BackColor = System.Drawing.Color.LimeGreen;
+ startButton.Enabled = true;
+ }
+ else
+ {
+ //if there is an error with the production weather station, display a tooltip & do not let the user start the telescope
+ this.WCOMPortToolTip.Show("Could not create production weather station on this port.", label8);
+ txtWSCOMPort.BackColor = System.Drawing.Color.Yellow;
+ }
+
+ }
+ else
+ {
+ startButton.BackColor = System.Drawing.Color.LimeGreen;
+ startButton.Enabled = true;
+ }
+
+ //Editing text to relflect state -- When the settings are being edited, the button will need to say 'finalize'
+ acceptSettings.Text = "Edit Settings";
+
+ startRTGroupbox.BackColor = System.Drawing.Color.Gray;
+ loopBackBox.Enabled = false;
+
+ simulationSettingsGroupbox.BackColor = System.Drawing.Color.DarkGray;
+ comboSensorNetworkBox.Enabled = false;
+ comboWeatherStationBox.Enabled = false;
+ comboSpectraCyberBox.Enabled = false;
+ comboPLCType.Enabled = false;
+ LocalIPCombo.Enabled = false;
+
+ portGroupbox.BackColor = System.Drawing.Color.DarkGray;
+ ProdcheckBox.Enabled = false;
+ txtPLCIP.Enabled = false;
+ txtMcuCOMPort.Enabled = false;
+ txtWSCOMPort.Enabled = false;
+ txtPLCPort.Enabled = false;
+ txtSpectraPort.Enabled = false;
+
+ sensorNetworkServerIPAddress.Enabled = false;
+ sensorNetworkServerPort.Enabled = false;
+ sensorNetworkClientIPAddress.Enabled = false;
+ sensorNetworkClientPort.Enabled = false;
+
+ }
+ else if (finalSettings == true)
+ {
+ // Editing Text to reflect state -- when finalized, you can click "edit settings"
+ acceptSettings.Text = "Finalize Settings";
+
+ //hide WS error
+ this.WCOMPortToolTip.Hide(label8);
+ txtWSCOMPort.BackColor = System.Drawing.Color.White;
+
+
+ startRTGroupbox.BackColor = System.Drawing.Color.DarkGray;
+ startButton.Enabled = false;
+ startButton.BackColor = System.Drawing.Color.LightGray;
+ loopBackBox.Enabled = true;
+
+ simulationSettingsGroupbox.BackColor = System.Drawing.Color.Gray;
+ comboSensorNetworkBox.Enabled = true;
+ comboWeatherStationBox.Enabled = true;
+ comboSpectraCyberBox.Enabled = true;
+ comboPLCType.Enabled = true;
+ LocalIPCombo.Enabled = true;
+
+ portGroupbox.BackColor = System.Drawing.Color.Gray;
+ ProdcheckBox.Enabled = true;
+ txtPLCIP.Enabled = true;
+ txtMcuCOMPort.Enabled = true;
+ txtWSCOMPort.Enabled = true;
+ txtPLCPort.Enabled = true;
+ txtSpectraPort.Enabled = true;
+
+ sensorNetworkServerIPAddress.Enabled = true;
+ sensorNetworkServerPort.Enabled = true;
+ sensorNetworkClientIPAddress.Enabled = true;
+ sensorNetworkClientPort.Enabled = true;
+ }
+
+ }
+
+ //Help button clicked ( user interface documentation PDF)
+ private void helpButton_click(object sender, EventArgs e)
+ {
+ string filename = Directory.GetCurrentDirectory() + "\\" + "UIDoc.pdf";
+ if (File.Exists(filename))
+ System.Diagnostics.Process.Start(filename);
+ }
+
+ private void simulationSettingsGroupbox_Enter(object sender, EventArgs e)
+ {
+
+ }
+
+ private void portGroupbox_Enter(object sender, EventArgs e)
+ {
+
+ }
+
+ // Get and set Weather Station override status
+
+ public void setWSOverride(bool WSO)
+ {
+ MainControlRoomController.ControlRoom.weatherStationOverride = WSO;
+ DatabaseOperations.SetOverrideForSensor(SensorItemEnum.WEATHER_STATION, WSO);
+ }
+
+ public bool getWSOverride()
+ {
+ return MainControlRoomController.ControlRoom.weatherStationOverride;
+ }
+
+ private void txtMcuCOMPort_TextChanged(object sender, EventArgs e)
+ {
+ MCUPortValid = Validator.ValidatePort(txtMcuCOMPort.Text);
+ if (!MCUPortValid)
+ {
+ acceptSettings.Enabled = false;
+ txtMcuCOMPort.BackColor = System.Drawing.Color.Yellow;
+ this.MCUIPToolTip.Show("Enter a valid port number\n" +
+ "between 1 and 65536", label5);
+ }
+ else
+ {
+ txtMcuCOMPort.BackColor = System.Drawing.Color.White;
+ this.MCUIPToolTip.Hide(label5);
+ }
+ if (RLPortValid && PLCPortValid && MCUPortValid && MCUIPValid && WCOMPortValid && SensorNetworkServerIPBool && SensorNetworkServerPortBool && SensorNetworkClientIPBool && SensorNetworkClientPortBool)
+ {
+ acceptSettings.Enabled = true;
+ }
+ }
+
+ private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
+ {
+
+ }
+
+ private void comboBox2_SelectedIndexChanged(object sender, EventArgs e)
+ {
+
+ }
+
+ private void comboEncoderType_SelectedIndexChanged(object sender, EventArgs e)
+ {
+
+ }
+
+ private void comboPLCType_SelectedIndexChanged(object sender, EventArgs e)
+ {
+
+ }
+
+ private void sensorNetworkServerIPAddress_TextChanged(object sender, EventArgs e)
+ {
+ if (sensorNetworkServerIPAddress.Text != "IP Address")
+ {
+ SensorNetworkServerIPBool = Validator.ValidateIPAddress(sensorNetworkServerIPAddress.Text);
+ if (!SensorNetworkServerIPBool)
+ {
+ acceptSettings.Enabled = false;
+ sensorNetworkServerIPAddress.BackColor = System.Drawing.Color.Yellow;
+ this.MCUIPToolTip.Show("Enter a valid IP Address\n" +
+ " (xxx.xxx.xxx.xxx)", label6);
+ }
+ else
+ {
+ sensorNetworkServerIPAddress.BackColor = System.Drawing.Color.White;
+ this.MCUIPToolTip.Hide(label6);
+ }
+ if (RLPortValid && PLCPortValid && MCUPortValid && MCUIPValid && WCOMPortValid && SensorNetworkServerIPBool && SensorNetworkServerPortBool && SensorNetworkClientIPBool && SensorNetworkClientPortBool)
+ {
+ acceptSettings.Enabled = true;
+ }
+ }
+ else
+ {
+ sensorNetworkServerIPAddress.BackColor = System.Drawing.Color.LightGray;
+ this.MCUIPToolTip.Hide(label6);
+ }
+ }
+
+ //Sets removes the temp value and sets text to black
+ private void sensorNetworkServerIPAddress_Enter(object sender, EventArgs e)
+ {
+ if (sensorNetworkServerIPAddress.Text == "IP Address")
+ {
+ sensorNetworkServerIPAddress.Text = "";
+ sensorNetworkServerIPAddress.ForeColor = System.Drawing.Color.Black;
+ }
+ }
+
+ //Sets sets the temp value and sets text to gray
+ private void sensorNetworkServerIPAddress_Leave(object sender, EventArgs e)
+ {
+ if (sensorNetworkServerIPAddress.Text == "")
+ {
+ sensorNetworkServerIPAddress.Text = "IP Address";
+ sensorNetworkServerIPAddress.ForeColor = System.Drawing.Color.Gray;
+ }
+ }
+
+ private void sensorNetworkClientIPAddress_TextChanged(object sender, EventArgs e)
+ {
+ if (sensorNetworkClientIPAddress.Text != "IP Address")
+ {
+ SensorNetworkClientIPBool = Validator.ValidateIPAddress(sensorNetworkClientIPAddress.Text);
+ if (!SensorNetworkClientIPBool)
+ {
+ acceptSettings.Enabled = false;
+ sensorNetworkClientIPAddress.BackColor = System.Drawing.Color.Yellow;
+ this.MCUIPToolTip.Show("Enter a valid IP Address\n" +
+ " (xxx.xxx.xxx.xxx)", label7);
+ }
+ else
+ {
+ sensorNetworkClientIPAddress.BackColor = System.Drawing.Color.White;
+ this.MCUIPToolTip.Hide(label7);
+ }
+ if (RLPortValid && PLCPortValid && MCUPortValid && MCUIPValid && WCOMPortValid && SensorNetworkServerIPBool && SensorNetworkServerPortBool && SensorNetworkClientIPBool && SensorNetworkClientPortBool)
+ {
+ acceptSettings.Enabled = true;
+ }
+ }
+ else
+ {
+ sensorNetworkClientIPAddress.BackColor = System.Drawing.Color.LightGray;
+ this.MCUIPToolTip.Hide(label7);
+ }
+ }
+
+ //Sets removes the temp value and sets text to black
+ private void sensorNetworkClientIPAddress_Enter(object sender, EventArgs e)
+ {
+ if (sensorNetworkClientIPAddress.Text == "IP Address")
+ {
+ sensorNetworkClientIPAddress.Text = "";
+ sensorNetworkClientIPAddress.ForeColor = System.Drawing.Color.Black;
+ }
+ }
+
+ //Sets sets the temp value and sets text to gray
+ private void sensorNetworkClientIPAddress_Leave(object sender, EventArgs e)
+ {
+ if (sensorNetworkClientIPAddress.Text == "")
+ {
+ sensorNetworkClientIPAddress.Text = "IP Address";
+ sensorNetworkClientIPAddress.ForeColor = System.Drawing.Color.Gray;
+ }
+ }
+
+ private void sensorNetworkServerPort_TextChanged(object sender, EventArgs e)
+ {
+ if (sensorNetworkServerPort.Text != "Port")
+ {
+ SensorNetworkServerPortBool = Validator.ValidatePort(sensorNetworkServerPort.Text);
+ if (!SensorNetworkServerPortBool)
+ {
+ acceptSettings.Enabled = false;
+ sensorNetworkServerPort.BackColor = System.Drawing.Color.Yellow;
+ this.WCOMPortToolTip.Show("Enter a valid port number\n" +
+ " between 1 and 65536", label6);
+ }
+ else
+ {
+ sensorNetworkServerPort.BackColor = System.Drawing.Color.White;
+ this.WCOMPortToolTip.Hide(label6);
+
+ }
+ if (RLPortValid && PLCPortValid && MCUPortValid && MCUIPValid && WCOMPortValid && SensorNetworkServerIPBool && SensorNetworkServerPortBool && SensorNetworkClientIPBool && SensorNetworkClientPortBool)
+ {
+ acceptSettings.Enabled = true;
+ }
+ }
+ else
+ {
+ sensorNetworkServerPort.BackColor = System.Drawing.Color.LightGray;
+ this.WCOMPortToolTip.Hide(label6);
+ }
+ }
+
+ //Sets removes the temp value and sets text to black
+ private void sensorNetworkServerPort_Enter(object sender, EventArgs e)
+ {
+ if (sensorNetworkServerPort.Text == "Port")
+ {
+ sensorNetworkServerPort.Text = "";
+ sensorNetworkServerPort.ForeColor = System.Drawing.Color.Black;
+ }
+ }
+
+ //Sets sets the temp value and sets text to gray
+ private void sensorNetworkServerPort_Leave(object sender, EventArgs e)
+ {
+ if (sensorNetworkServerPort.Text == "")
+ {
+ sensorNetworkServerPort.Text = "Port";
+ sensorNetworkServerPort.ForeColor = System.Drawing.Color.Gray;
+ }
+ }
+
+ //Sets removes the temp value and sets text to black
+ private void txtSpectraPort_Enter(object sender, EventArgs e)
+ {
+ if (txtSpectraPort.Text == "COM")
+ {
+ txtSpectraPort.Text = "";
+ txtSpectraPort.ForeColor = System.Drawing.Color.Black;
+ }
+ }
+
+ //Sets sets the temp value and sets text to gray
+ private void txtSpectraPort_Leave(object sender, EventArgs e)
+ {
+ if (txtSpectraPort.Text == "")
+ {
+ txtSpectraPort.Text = "COM";
+ txtSpectraPort.ForeColor = System.Drawing.Color.Gray;
+ }
+ }
+
+ //Sets removes the temp value and sets text to black
+ private void txtWSCOMPort_Enter(object sender, EventArgs e)
+ {
+ if (txtWSCOMPort.Text == "COM")
+ {
+ txtWSCOMPort.Text = "";
+ txtWSCOMPort.ForeColor = System.Drawing.Color.Black;
+ }
+ }
+
+ //Sets sets the temp value and sets text to gray
+ private void txtWSCOMPort_Leave(object sender, EventArgs e)
+ {
+ if (txtWSCOMPort.Text == "")
+ {
+ txtWSCOMPort.Text = "COM";
+ txtWSCOMPort.ForeColor = System.Drawing.Color.Gray;
+ }
+ }
+
+
+ //Sets removes the temp value and sets text to black
+ private void txtRemoteListenerCOMPort_Enter(object sender, EventArgs e)
+ {
+ if (txtRemoteListenerCOMPort.Text == "COM")
+ {
+ txtRemoteListenerCOMPort.Text = "";
+ txtRemoteListenerCOMPort.ForeColor = System.Drawing.Color.Black;
+ }
+ }
+
+ //Sets sets the temp value and sets text to gray
+ private void txtRemoteListenerCOMPort_Leave(object sender, EventArgs e)
+ {
+ if (txtRemoteListenerCOMPort.Text == "")
+ {
+ txtRemoteListenerCOMPort.Text = "COM";
+ txtRemoteListenerCOMPort.ForeColor = System.Drawing.Color.Gray;
+ }
+ }
+
+
+ private void sensorNetworkClientPort_TextChanged(object sender, EventArgs e)
+ {
+ if (sensorNetworkClientPort.Text != "Port")
+ {
+ SensorNetworkClientPortBool = Validator.ValidatePort(sensorNetworkClientPort.Text);
+ if (!SensorNetworkClientPortBool)
+ {
+ acceptSettings.Enabled = false;
+ sensorNetworkClientPort.BackColor = System.Drawing.Color.Yellow;
+ this.WCOMPortToolTip.Show("Enter a valid port number\n" +
+ " between 1 and 65536", label7);
+ }
+ else
+ {
+ sensorNetworkClientPort.BackColor = System.Drawing.Color.White;
+ this.WCOMPortToolTip.Hide(label7);
+
+ }
+ if (RLPortValid && PLCPortValid && MCUPortValid && MCUIPValid && WCOMPortValid && SensorNetworkServerIPBool && SensorNetworkServerPortBool && SensorNetworkClientIPBool && SensorNetworkClientPortBool)
+ {
+ acceptSettings.Enabled = true;
+ }
+ }
+ else
+ {
+ sensorNetworkClientPort.BackColor = System.Drawing.Color.LightGray;
+ this.WCOMPortToolTip.Hide(label7);
+ }
+ }
+
+ //Sets removes the temp value and sets text to black
+ private void sensorNetworkClientPort_Enter(object sender, EventArgs e)
+ {
+ if (sensorNetworkClientPort.Text == "Port")
+ {
+ sensorNetworkClientPort.Text = "";
+ sensorNetworkClientPort.ForeColor = System.Drawing.Color.Black;
+ }
+ }
+
+ //Sets sets the temp value and sets text to gray
+ private void sensorNetworkClientPort_Leave(object sender, EventArgs e)
+ {
+ if (sensorNetworkClientPort.Text == "")
+ {
+ sensorNetworkClientPort.Text = "Port";
+ sensorNetworkClientPort.ForeColor = System.Drawing.Color.Gray;
+ }
+ }
+
+ private void WCOMPortToolTip_Popup(object sender, PopupEventArgs e)
+ {
+
+ }
+
+ private void textBox1_TextChanged(object sender, EventArgs e)
+ {
+ if (txtSpectraPort.Text != "COM")
+ {
+ SpectraPortValid = Validator.ValidatePort(txtSpectraPort.Text);
+ if (!SpectraPortValid)
+ {
+ acceptSettings.Enabled = false;
+ txtSpectraPort.BackColor = System.Drawing.Color.Yellow;
+ this.WCOMPortToolTip.Show("Enter a valid port number\n" +
+ " between 1 and 65536", label8);
+ }
+ else
+ {
+ txtSpectraPort.BackColor = System.Drawing.Color.White;
+ this.WCOMPortToolTip.Hide(label8);
+
+ }
+ if (RLPortValid && PLCPortValid && MCUPortValid && MCUIPValid && WCOMPortValid && SensorNetworkServerIPBool && SensorNetworkServerPortBool && SensorNetworkClientIPBool && SensorNetworkClientPortBool && SpectraPortValid)
+ {
+ acceptSettings.Enabled = true;
+ }
+ }
+ else
+ {
+ txtSpectraPort.BackColor = System.Drawing.Color.LightGray;
+ this.WCOMPortToolTip.Hide(label8);
+ }
}
}
}
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/GUI/MainForm.resx b/ControlRoomApplication/ControlRoomApplication/GUI/MainForm.resx
index 1af7de15..87441498 100644
--- a/ControlRoomApplication/ControlRoomApplication/GUI/MainForm.resx
+++ b/ControlRoomApplication/ControlRoomApplication/GUI/MainForm.resx
@@ -117,4 +117,34 @@
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+ 552, 17
+
+
+ 17, 17
+
+
+ 417, 17
+
+
+ 145, 17
+
+
+ 275, 17
+
+
+ 145, 17
+
+
+ 275, 17
+
+
+ 417, 17
+
+
+ 17, 17
+
+
+ 552, 17
+
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/GUI/ManualControl.Designer.cs b/ControlRoomApplication/ControlRoomApplication/GUI/ManualControl.Designer.cs
new file mode 100644
index 00000000..152b0493
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/GUI/ManualControl.Designer.cs
@@ -0,0 +1,198 @@
+namespace ControlRoomApplication.Main
+{
+ partial class EditScriptsForm
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ //protected override void Dispose(bool disposing)
+ //{
+ // if (disposing && (components != null))
+ // {
+ // components.Dispose();
+ // }
+ // //base.Dispose(disposing);
+ //}
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.components = new System.ComponentModel.Container();
+ this.timer1 = new System.Windows.Forms.Timer(this.components);
+ this.label1 = new System.Windows.Forms.Label();
+ this.label2 = new System.Windows.Forms.Label();
+ this.comboBox1 = new System.Windows.Forms.ComboBox();
+ this.textBox1 = new System.Windows.Forms.TextBox();
+ this.button1 = new System.Windows.Forms.Button();
+ this.button2 = new System.Windows.Forms.Button();
+ this.button3 = new System.Windows.Forms.Button();
+ this.splitContainer1 = new System.Windows.Forms.SplitContainer();
+ this.button4 = new System.Windows.Forms.Button();
+ ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();
+ this.splitContainer1.Panel1.SuspendLayout();
+ this.splitContainer1.Panel2.SuspendLayout();
+ this.splitContainer1.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // timer1
+ //
+ this.timer1.Enabled = true;
+ this.timer1.Interval = 1000;
+ //
+ // label1
+ //
+ this.label1.AutoSize = true;
+ this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.label1.Location = new System.Drawing.Point(1, 9);
+ this.label1.Name = "label1";
+ this.label1.Size = new System.Drawing.Size(103, 24);
+ this.label1.TabIndex = 0;
+ this.label1.Text = "Edit Scripts";
+ //
+ // label2
+ //
+ this.label2.AutoSize = true;
+ this.label2.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.label2.Location = new System.Drawing.Point(19, 10);
+ this.label2.Name = "label2";
+ this.label2.Size = new System.Drawing.Size(94, 16);
+ this.label2.TabIndex = 0;
+ this.label2.Text = "Current Scripts";
+ //
+ // comboBox1
+ //
+ this.comboBox1.FormattingEnabled = true;
+ this.comboBox1.Location = new System.Drawing.Point(11, 29);
+ this.comboBox1.Name = "comboBox1";
+ this.comboBox1.Size = new System.Drawing.Size(160, 21);
+ this.comboBox1.TabIndex = 1;
+ this.comboBox1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.comboBox1.SelectedIndexChanged += new System.EventHandler(this.comboBox1_SelectedIndexChanged);
+ //
+ // textBox1
+ //
+ this.textBox1.Location = new System.Drawing.Point(11, 22);
+ this.textBox1.MaximumSize = new System.Drawing.Size(1000, 1000);
+ this.textBox1.Name = "textBox1";
+ this.textBox1.Size = new System.Drawing.Size(252, 20);
+ this.textBox1.TabIndex = 2;
+ this.textBox1.Text = "C:\\Users\\RadioTelescope\\Scripts";
+ //
+ // button1
+ //
+ this.button1.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+ this.button1.Location = new System.Drawing.Point(292, 22);
+ this.button1.MaximumSize = new System.Drawing.Size(1000, 1000);
+ this.button1.Name = "button1";
+ this.button1.Size = new System.Drawing.Size(25, 25);
+ this.button1.TabIndex = 3;
+ this.button1.Text = "...";
+ this.button1.UseVisualStyleBackColor = true;
+ //
+ // button2
+ //
+ this.button2.BackColor = System.Drawing.Color.Silver;
+ this.button2.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+ this.button2.Location = new System.Drawing.Point(219, 29);
+ this.button2.Name = "button2";
+ this.button2.Size = new System.Drawing.Size(98, 23);
+ this.button2.TabIndex = 4;
+ this.button2.Text = "Remove Script";
+ this.button2.UseVisualStyleBackColor = false;
+ this.button2.Click += new System.EventHandler(this.button2_Click);
+ //
+ // button3
+ //
+ this.button3.BackColor = System.Drawing.Color.Silver;
+ this.button3.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+ this.button3.Location = new System.Drawing.Point(219, 67);
+ this.button3.MaximumSize = new System.Drawing.Size(1000, 1000);
+ this.button3.Name = "button3";
+ this.button3.Size = new System.Drawing.Size(98, 23);
+ this.button3.TabIndex = 5;
+ this.button3.Text = "Add Script";
+ this.button3.UseVisualStyleBackColor = false;
+ this.button3.Click += new System.EventHandler(this.button3_Click);
+ //
+ // splitContainer1
+ //
+ this.splitContainer1.BackColor = System.Drawing.Color.Gainsboro;
+ this.splitContainer1.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
+ this.splitContainer1.Location = new System.Drawing.Point(2, 12);
+ this.splitContainer1.Name = "splitContainer1";
+ this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal;
+ //
+ // splitContainer1.Panel1
+ //
+ this.splitContainer1.Panel1.BackColor = System.Drawing.Color.DarkGray;
+ this.splitContainer1.Panel1.Controls.Add(this.comboBox1);
+ this.splitContainer1.Panel1.Controls.Add(this.label2);
+ this.splitContainer1.Panel1.Controls.Add(this.button2);
+ this.splitContainer1.Panel1.Paint += new System.Windows.Forms.PaintEventHandler(this.splitContainer1_Panel1_Paint);
+ //
+ // splitContainer1.Panel2
+ //
+ this.splitContainer1.Panel2.BackColor = System.Drawing.Color.DarkGray;
+ this.splitContainer1.Panel2.Controls.Add(this.textBox1);
+ this.splitContainer1.Panel2.Controls.Add(this.button3);
+ this.splitContainer1.Panel2.Controls.Add(this.button1);
+ this.splitContainer1.Panel2.Paint += new System.Windows.Forms.PaintEventHandler(this.splitContainer1_Panel2_Paint);
+ this.splitContainer1.Size = new System.Drawing.Size(331, 187);
+ this.splitContainer1.SplitterDistance = 74;
+ this.splitContainer1.TabIndex = 6;
+ //
+ // button4
+ //
+ this.button4.BackColor = System.Drawing.Color.LimeGreen;
+ this.button4.Cursor = System.Windows.Forms.Cursors.Hand;
+ this.button4.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+ this.button4.Location = new System.Drawing.Point(199, 204);
+ this.button4.Name = "button4";
+ this.button4.Size = new System.Drawing.Size(129, 23);
+ this.button4.TabIndex = 7;
+ this.button4.Text = "Apply Changes";
+ this.button4.UseVisualStyleBackColor = false;
+ //
+ // EditScriptsForm
+ //
+ this.BackColor = System.Drawing.Color.Gainsboro;
+ this.ClientSize = new System.Drawing.Size(333, 232);
+ this.Controls.Add(this.button4);
+ this.Controls.Add(this.splitContainer1);
+ this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
+ this.Name = "EditScriptsForm";
+ this.Text = "Edit Scripts";
+ this.splitContainer1.Panel1.ResumeLayout(false);
+ this.splitContainer1.Panel1.PerformLayout();
+ this.splitContainer1.Panel2.ResumeLayout(false);
+ this.splitContainer1.Panel2.PerformLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit();
+ this.splitContainer1.ResumeLayout(false);
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+ private System.Windows.Forms.Timer timer1;
+ private System.Windows.Forms.Label label1;
+ private System.Windows.Forms.Label label2;
+ private System.Windows.Forms.ComboBox comboBox1;
+ private System.Windows.Forms.TextBox textBox1;
+ private System.Windows.Forms.Button button1;
+ private System.Windows.Forms.Button button2;
+ private System.Windows.Forms.Button button3;
+ private System.Windows.Forms.SplitContainer splitContainer1;
+ private System.Windows.Forms.Button button4;
+ }
+}
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/GUI/ManualControl.cs b/ControlRoomApplication/ControlRoomApplication/GUI/ManualControl.cs
new file mode 100644
index 00000000..e2a0f3be
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/GUI/ManualControl.cs
@@ -0,0 +1,230 @@
+using System;
+using System.Windows.Forms;
+using ControlRoomApplication.Entities;
+using ControlRoomApplication.Controllers;
+using System.Threading.Tasks;
+using ControlRoomApplication.Constants;
+using ControlRoomApplication.Util;
+
+
+namespace ControlRoomApplication.Main
+{
+ public partial class EditScriptsForm : Form
+ {
+ public RadioTelescopeController rt_controller { get; set; }
+ public ControlRoom controlRoom { get; set; }
+ public double speed { get; set; }
+ private static readonly log4net.ILog logger =
+ log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
+
+ public EditScriptsForm(ControlRoom new_controlRoom, int rtId)
+ {
+ InitializeComponent();
+
+ // Set ControlRoom
+ controlRoom = new_controlRoom;
+
+ // Make rt_controller
+ rt_controller = controlRoom.RadioTelescopeControllers[rtId - 1];
+
+ // Update Text
+ UpdateText("Edit Scripts in Control Form for Radio Telescope " + rt_controller.RadioTelescope.Id.ToString());
+
+ // Set speed
+ // comboBox1.Text = "0.1 RPM";
+ speed = 0.1;
+
+ logger.Info(Utilities.GetTimeStamp() + ": Edit Script Form Initalized");
+ }
+
+ private void ManualControlForm_FormClosing(Object sender, FormClosingEventArgs e)
+ {
+ logger.Info(Utilities.GetTimeStamp() + ": Edit Script Form Closing");
+ timer1.Enabled = false;
+ }
+
+ private void UpdateText(string text)
+ {
+ //errorLabel.Text = text;
+ }
+
+ private void NegButton_MouseDown(object sender, MouseEventArgs e)
+ {
+ // logger.Info(Utilities.GetTimeStamp() + ": Jog NegButton MouseDown");
+ //UpdateText("Moving at -" + comboBox1.Text);
+
+ // Start CCW Jog
+ //rt_controller.StartRadioTelescopeAzimuthJog(speed, false, );
+ }
+
+ private void NegButton_MouseUp(object sender, MouseEventArgs e)
+ {
+ // logger.Info(Utilities.GetTimeStamp() + ": Jog NegButton MouseUp");
+ UpdateText("Manual Control for Radio Telescope " + rt_controller.RadioTelescope.Id.ToString());
+
+ // Stop Move
+ //ExecuteCorrectStop();
+ }
+
+ private void splitContainer1_Panel2_Paint(object sender, PaintEventArgs e)
+ {
+
+ }
+
+ private void splitContainer1_Panel1_Paint(object sender, PaintEventArgs e)
+ {
+
+ }
+
+ private void button3_Click(object sender, EventArgs e)
+ {
+
+ }
+
+ private void button2_Click(object sender, EventArgs e)
+ {
+
+ }
+
+ private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
+ {
+
+ }
+ }
+}
+
+ // private void PosButton_MouseDown(object sender, MouseEventArgs e)
+ //// {
+ // logger.Info(Utilities.GetTimeStamp() + ": Jog PosButton MouseDown");
+ // // UpdateText("Moving at " + comboBox1.Text);
+
+// // Start CW Jog
+// rt_controller.StartRadioTelescopeAzimuthJog(speed, true);
+// // }
+
+// private void PosButton_MouseUp(object sender, MouseEventArgs e)
+//{
+// logger.Info(Utilities.GetTimeStamp() + ": Jog PosButton MouseUp");
+// UpdateText("Manual Control for Radio Telescope " + rt_controller.RadioTelescope.Id.ToString());
+
+// Stop Move
+//ExecuteCorrectStop();
+// }
+
+// private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
+// {
+// if(comboBox1.Text == "2 RPM")
+// {
+// logger.Info(Utilities.GetTimeStamp() + ": Speed set to 2 RPM");
+// speed = 333333;
+// }
+//// else if(comboBox1.Text == "0.1 RPM")
+// {
+// logger.Info(Utilities.GetTimeStamp() + ": Speed set to 0.1 RPM");
+// speed = 16667;
+// }
+
+//else
+//{
+// logger.Info(Utilities.GetTimeStamp() + ": Invalid Speed Selected");
+// throw new Exception();
+//}
+///
+
+//private void ExecuteCorrectStop()
+//{
+// // //if (ControlledButtonRadio.Checked)
+// // {
+// // logger.Info(Utilities.GetTimeStamp() + ": Executed Controlled Stop");
+// // rt_controller.ExecuteRadioTelescopeControlledStop();
+// // }
+// //// else if (radioButton2.Checked)
+// // {
+// // logger.Info(Utilities.GetTimeStamp() + ": Executed Immediate Stop");
+// // rt_controller.ExecuteRadioTelescopeImmediateStop();
+// // }
+// //else
+// //{
+// // logger.Info(Utilities.GetTimeStamp() + ": Invalid Stop Selected");
+// // throw new Exception();
+// //}
+//}
+
+//private void button1_Click(object sender, EventArgs e)
+//{//
+// // logger.Info(Utilities.GetTimeStamp() + ": Move Relative Button Clicked");
+// //int pos = (int)numericUpDown1.Value * (int)((166 + (2.0 / 3.0)) * 200);
+// //int pos = ConversionHelper.DegreesToSteps( (int)numericUpDown1.Value , MotorConstants.GEARING_RATIO_AZIMUTH );
+// // rt_controller.ExecuteMoveRelativeAzimuth(RadioTelescopeAxisEnum.AZIMUTH,speed, pos);
+//}
+
+//private void timer1_Tick(object sender, EventArgs e)
+//{
+// // Entities.Orientation currentOrienation = rt_controller.GetCurrentOrientation();
+// // SetActualAZText(currentOrienation.Azimuth.ToString("0.##"));
+// // SetActualELText(currentOrienation.Elevation.ToString("0.##"));
+//}
+
+// delegate void SetActualAZTextCallback(string text);
+//private void SetActualAZText(string text)
+//{
+// // InvokeRequired required compares the thread ID of the
+// // calling thread to the thread ID of the creating thread.
+// // If these threads are different, it returns true.
+// // if (ActualAZTextBox.InvokeRequired)
+// {
+// //SetActualAZTextCallback d = new SetActualAZTextCallback(SetActualAZText);
+// var d = new SetActualAZTextCallback(SetActualAZText);
+// try
+// {
+// var task = Task.Run( () => Invoke( d , new object[] { text } ));
+// if(!task.Wait( 300 ))
+// throw new Exception( "Timed out" );
+
+// }
+// catch {
+
+// }
+// }
+// else
+// {
+// // ActualAZTextBox.Text = text;
+// }
+//}
+
+//delegate void SetActualELTextCallback(string text);
+//private void SetActualELText(string text)
+//{ }
+// InvokeRequired required compares the thread ID of the
+// calling thread to the thread ID of the creating thread.
+// If these threads are different, it returns true.
+// if (ActualELTextBox.InvokeRequired)
+// {
+// //SetActualELTextCallback d = new SetActualELTextCallback(SetActualELText);
+// var d = new SetActualELTextCallback(SetActualELText);
+// try
+// {
+// var task = Task.Run( () => Invoke( d , new object[] { text } ) );
+// if(!task.Wait( 300 ))
+// throw new Exception( "Timed out" );
+
+// }
+// catch { }
+// }
+// else
+// {
+// ActualELTextBox.Text = text;
+// }
+//}
+
+// private void NegButton_Click(object sender, EventArgs e)
+// {
+
+// }
+
+// private void ManualControlForm_Load(object sender, EventArgs e)
+// {
+
+// }
+// }
+//}
diff --git a/ControlRoomApplication/ControlRoomApplication/GUI/FreeControlForm.resx b/ControlRoomApplication/ControlRoomApplication/GUI/ManualControl.resx
similarity index 100%
rename from ControlRoomApplication/ControlRoomApplication/GUI/FreeControlForm.resx
rename to ControlRoomApplication/ControlRoomApplication/GUI/ManualControl.resx
diff --git a/ControlRoomApplication/ControlRoomApplication/GUI/ManualControlForm.Designer.cs b/ControlRoomApplication/ControlRoomApplication/GUI/ManualControlForm.Designer.cs
deleted file mode 100644
index 5b9aebd4..00000000
--- a/ControlRoomApplication/ControlRoomApplication/GUI/ManualControlForm.Designer.cs
+++ /dev/null
@@ -1,293 +0,0 @@
-namespace ControlRoomApplication.Main
-{
- partial class ManualControlForm
- {
- ///
- /// Required designer variable.
- ///
- private System.ComponentModel.IContainer components = null;
-
- ///
- /// Clean up any resources being used.
- ///
- /// true if managed resources should be disposed; otherwise, false.
- protected override void Dispose(bool disposing)
- {
- if (disposing && (components != null))
- {
- components.Dispose();
- }
- base.Dispose(disposing);
- }
-
- #region Windows Form Designer generated code
-
- ///
- /// Required method for Designer support - do not modify
- /// the contents of this method with the code editor.
- ///
- private void InitializeComponent()
- {
- this.components = new System.ComponentModel.Container();
- this.NegButton = new System.Windows.Forms.Button();
- this.PosButton = new System.Windows.Forms.Button();
- this.Title = new System.Windows.Forms.Label();
- this.errorLabel = new System.Windows.Forms.Label();
- this.comboBox1 = new System.Windows.Forms.ComboBox();
- this.label1 = new System.Windows.Forms.Label();
- this.radioButton1 = new System.Windows.Forms.RadioButton();
- this.radioButton2 = new System.Windows.Forms.RadioButton();
- this.button1 = new System.Windows.Forms.Button();
- this.label2 = new System.Windows.Forms.Label();
- this.numericUpDown1 = new System.Windows.Forms.NumericUpDown();
- this.timer1 = new System.Windows.Forms.Timer(this.components);
- this.ActualELLabel = new System.Windows.Forms.Label();
- this.ActualAZLabel = new System.Windows.Forms.Label();
- this.ActualPositionLabel = new System.Windows.Forms.Label();
- this.ActualELTextBox = new System.Windows.Forms.TextBox();
- this.ActualAZTextBox = new System.Windows.Forms.TextBox();
- ((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).BeginInit();
- this.SuspendLayout();
- //
- // NegButton
- //
- this.NegButton.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
- this.NegButton.BackColor = System.Drawing.Color.LightGray;
- this.NegButton.Location = new System.Drawing.Point(300, 201);
- this.NegButton.Name = "NegButton";
- this.NegButton.Size = new System.Drawing.Size(75, 54);
- this.NegButton.TabIndex = 2;
- this.NegButton.Text = "- Jog";
- this.NegButton.UseVisualStyleBackColor = false;
- this.NegButton.MouseDown += new System.Windows.Forms.MouseEventHandler(this.NegButton_MouseDown);
- this.NegButton.MouseUp += new System.Windows.Forms.MouseEventHandler(this.NegButton_MouseUp);
- //
- // PosButton
- //
- this.PosButton.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
- this.PosButton.BackColor = System.Drawing.Color.LightGray;
- this.PosButton.Location = new System.Drawing.Point(455, 201);
- this.PosButton.Name = "PosButton";
- this.PosButton.Size = new System.Drawing.Size(75, 54);
- this.PosButton.TabIndex = 3;
- this.PosButton.Text = "+ Jog";
- this.PosButton.UseVisualStyleBackColor = false;
- this.PosButton.MouseDown += new System.Windows.Forms.MouseEventHandler(this.PosButton_MouseDown);
- this.PosButton.MouseUp += new System.Windows.Forms.MouseEventHandler(this.PosButton_MouseUp);
- //
- // Title
- //
- this.Title.Anchor = System.Windows.Forms.AnchorStyles.Top;
- this.Title.AutoSize = true;
- this.Title.Font = new System.Drawing.Font("Microsoft Sans Serif", 30F);
- this.Title.Location = new System.Drawing.Point(297, 28);
- this.Title.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
- this.Title.Name = "Title";
- this.Title.Size = new System.Drawing.Size(291, 46);
- this.Title.TabIndex = 15;
- this.Title.Text = "Manual Control";
- //
- // errorLabel
- //
- this.errorLabel.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
- this.errorLabel.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
- this.errorLabel.ForeColor = System.Drawing.Color.Red;
- this.errorLabel.Location = new System.Drawing.Point(300, 411);
- this.errorLabel.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
- this.errorLabel.Name = "errorLabel";
- this.errorLabel.Size = new System.Drawing.Size(230, 19);
- this.errorLabel.TabIndex = 18;
- this.errorLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
- //
- // comboBox1
- //
- this.comboBox1.Anchor = System.Windows.Forms.AnchorStyles.Top;
- this.comboBox1.FormattingEnabled = true;
- this.comboBox1.Items.AddRange(new object[] {
- "0.1 RPM",
- "2 RPM"});
- this.comboBox1.Location = new System.Drawing.Point(353, 111);
- this.comboBox1.Name = "comboBox1";
- this.comboBox1.Size = new System.Drawing.Size(121, 21);
- this.comboBox1.TabIndex = 19;
- this.comboBox1.SelectedIndexChanged += new System.EventHandler(this.comboBox1_SelectedIndexChanged);
- //
- // label1
- //
- this.label1.Anchor = System.Windows.Forms.AnchorStyles.Top;
- this.label1.AutoSize = true;
- this.label1.Location = new System.Drawing.Point(391, 95);
- this.label1.Name = "label1";
- this.label1.Size = new System.Drawing.Size(38, 13);
- this.label1.TabIndex = 20;
- this.label1.Text = "Speed";
- //
- // radioButton1
- //
- this.radioButton1.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
- this.radioButton1.AutoSize = true;
- this.radioButton1.Checked = true;
- this.radioButton1.Location = new System.Drawing.Point(366, 319);
- this.radioButton1.Name = "radioButton1";
- this.radioButton1.Size = new System.Drawing.Size(97, 17);
- this.radioButton1.TabIndex = 21;
- this.radioButton1.TabStop = true;
- this.radioButton1.Text = "Controlled Stop";
- this.radioButton1.UseVisualStyleBackColor = true;
- //
- // radioButton2
- //
- this.radioButton2.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
- this.radioButton2.AutoSize = true;
- this.radioButton2.Location = new System.Drawing.Point(365, 342);
- this.radioButton2.Name = "radioButton2";
- this.radioButton2.Size = new System.Drawing.Size(98, 17);
- this.radioButton2.TabIndex = 22;
- this.radioButton2.Text = "Immediate Stop";
- this.radioButton2.UseVisualStyleBackColor = true;
- //
- // button1
- //
- this.button1.Anchor = System.Windows.Forms.AnchorStyles.Right;
- this.button1.Location = new System.Drawing.Point(640, 258);
- this.button1.Name = "button1";
- this.button1.Size = new System.Drawing.Size(120, 24);
- this.button1.TabIndex = 23;
- this.button1.Text = "Move Relative";
- this.button1.UseVisualStyleBackColor = true;
- this.button1.Click += new System.EventHandler(this.button1_Click);
- //
- // label2
- //
- this.label2.Anchor = System.Windows.Forms.AnchorStyles.Right;
- this.label2.AutoSize = true;
- this.label2.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F);
- this.label2.Location = new System.Drawing.Point(636, 161);
- this.label2.Name = "label2";
- this.label2.Size = new System.Drawing.Size(115, 20);
- this.label2.TabIndex = 24;
- this.label2.Text = "Target Position";
- //
- // numericUpDown1
- //
- this.numericUpDown1.Anchor = System.Windows.Forms.AnchorStyles.Right;
- this.numericUpDown1.Location = new System.Drawing.Point(640, 209);
- this.numericUpDown1.Maximum = new decimal(new int[] {
- 90000,
- 0,
- 0,
- 0});
- this.numericUpDown1.Minimum = new decimal(new int[] {
- 90000,
- 0,
- 0,
- -2147483648});
- this.numericUpDown1.Name = "numericUpDown1";
- this.numericUpDown1.Size = new System.Drawing.Size(120, 20);
- this.numericUpDown1.TabIndex = 25;
- //
- // timer1
- //
- this.timer1.Enabled = true;
- this.timer1.Interval = 1000;
- this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
- //
- // ActualELLabel
- //
- this.ActualELLabel.Anchor = System.Windows.Forms.AnchorStyles.Left;
- this.ActualELLabel.AutoSize = true;
- this.ActualELLabel.Location = new System.Drawing.Point(63, 244);
- this.ActualELLabel.Name = "ActualELLabel";
- this.ActualELLabel.Size = new System.Drawing.Size(51, 13);
- this.ActualELLabel.TabIndex = 30;
- this.ActualELLabel.Text = "Elevation";
- //
- // ActualAZLabel
- //
- this.ActualAZLabel.Anchor = System.Windows.Forms.AnchorStyles.Left;
- this.ActualAZLabel.AutoSize = true;
- this.ActualAZLabel.Location = new System.Drawing.Point(63, 191);
- this.ActualAZLabel.Name = "ActualAZLabel";
- this.ActualAZLabel.Size = new System.Drawing.Size(44, 13);
- this.ActualAZLabel.TabIndex = 29;
- this.ActualAZLabel.Text = "Azimuth";
- //
- // ActualPositionLabel
- //
- this.ActualPositionLabel.Anchor = System.Windows.Forms.AnchorStyles.Left;
- this.ActualPositionLabel.AutoSize = true;
- this.ActualPositionLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F);
- this.ActualPositionLabel.Location = new System.Drawing.Point(61, 161);
- this.ActualPositionLabel.Name = "ActualPositionLabel";
- this.ActualPositionLabel.Size = new System.Drawing.Size(114, 20);
- this.ActualPositionLabel.TabIndex = 28;
- this.ActualPositionLabel.Text = "Actual Position";
- //
- // ActualELTextBox
- //
- this.ActualELTextBox.Anchor = System.Windows.Forms.AnchorStyles.Left;
- this.ActualELTextBox.Location = new System.Drawing.Point(65, 262);
- this.ActualELTextBox.Name = "ActualELTextBox";
- this.ActualELTextBox.ReadOnly = true;
- this.ActualELTextBox.Size = new System.Drawing.Size(100, 20);
- this.ActualELTextBox.TabIndex = 27;
- //
- // ActualAZTextBox
- //
- this.ActualAZTextBox.Anchor = System.Windows.Forms.AnchorStyles.Left;
- this.ActualAZTextBox.Location = new System.Drawing.Point(65, 209);
- this.ActualAZTextBox.Name = "ActualAZTextBox";
- this.ActualAZTextBox.ReadOnly = true;
- this.ActualAZTextBox.Size = new System.Drawing.Size(100, 20);
- this.ActualAZTextBox.TabIndex = 26;
- //
- // ManualControlForm
- //
- this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
- this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
- this.ClientSize = new System.Drawing.Size(800, 450);
- this.Controls.Add(this.ActualELLabel);
- this.Controls.Add(this.ActualAZLabel);
- this.Controls.Add(this.ActualPositionLabel);
- this.Controls.Add(this.ActualELTextBox);
- this.Controls.Add(this.ActualAZTextBox);
- this.Controls.Add(this.numericUpDown1);
- this.Controls.Add(this.label2);
- this.Controls.Add(this.button1);
- this.Controls.Add(this.radioButton2);
- this.Controls.Add(this.radioButton1);
- this.Controls.Add(this.label1);
- this.Controls.Add(this.comboBox1);
- this.Controls.Add(this.errorLabel);
- this.Controls.Add(this.Title);
- this.Controls.Add(this.PosButton);
- this.Controls.Add(this.NegButton);
- this.MinimumSize = new System.Drawing.Size(816, 489);
- this.Name = "ManualControlForm";
- this.Text = "ManualControlForm";
- ((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).EndInit();
- this.ResumeLayout(false);
- this.PerformLayout();
-
- }
-
- #endregion
- private System.Windows.Forms.Button NegButton;
- private System.Windows.Forms.Button PosButton;
- private System.Windows.Forms.Label Title;
- private System.Windows.Forms.Label errorLabel;
- private System.Windows.Forms.ComboBox comboBox1;
- private System.Windows.Forms.Label label1;
- private System.Windows.Forms.RadioButton radioButton1;
- private System.Windows.Forms.RadioButton radioButton2;
- private System.Windows.Forms.Button button1;
- private System.Windows.Forms.Label label2;
- private System.Windows.Forms.NumericUpDown numericUpDown1;
- private System.Windows.Forms.Timer timer1;
- private System.Windows.Forms.Label ActualELLabel;
- private System.Windows.Forms.Label ActualAZLabel;
- private System.Windows.Forms.Label ActualPositionLabel;
- private System.Windows.Forms.TextBox ActualELTextBox;
- private System.Windows.Forms.TextBox ActualAZTextBox;
- }
-}
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/GUI/ManualControlForm.cs b/ControlRoomApplication/ControlRoomApplication/GUI/ManualControlForm.cs
deleted file mode 100644
index 74444e90..00000000
--- a/ControlRoomApplication/ControlRoomApplication/GUI/ManualControlForm.cs
+++ /dev/null
@@ -1,181 +0,0 @@
-using System;
-using System.Windows.Forms;
-using ControlRoomApplication.Entities;
-using ControlRoomApplication.Controllers;
-
-namespace ControlRoomApplication.Main
-{
- public partial class ManualControlForm : Form
- {
- public RadioTelescopeController rt_controller { get; set; }
- public ControlRoom controlRoom { get; set; }
- public int speed { get; set; }
- private static readonly log4net.ILog logger =
- log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
-
- public ManualControlForm(ControlRoom new_controlRoom, int rtId)
- {
- InitializeComponent();
-
- // Set ControlRoom
- controlRoom = new_controlRoom;
-
- // Make rt_controller
- rt_controller = controlRoom.RadioTelescopeControllers[rtId - 1];
-
- // Update Text
- UpdateText("Manual Control for Radio Telescope " + rt_controller.RadioTelescope.Id.ToString());
-
- // Set speed
- comboBox1.Text = "0.1 RPM";
- speed = 16667;
-
- logger.Info("ManualControlForm Initalized");
- }
-
- private void ManualControlForm_FormClosing(Object sender, FormClosingEventArgs e)
- {
- logger.Info("ManualControl Form Closing");
- timer1.Enabled = false;
- }
-
- private void UpdateText(string text)
- {
- errorLabel.Text = text;
- }
-
- private void NegButton_MouseDown(object sender, MouseEventArgs e)
- {
- logger.Info("Jog NegButton MouseDown");
- UpdateText("Moving at -" + comboBox1.Text);
-
- // Start CCW Jog
- rt_controller.StartRadioTelescopeAzimuthJog(speed, false);
- }
-
- private void NegButton_MouseUp(object sender, MouseEventArgs e)
- {
- logger.Info("Jog NegButton MouseUp");
- UpdateText("Manual Control for Radio Telescope " + rt_controller.RadioTelescope.Id.ToString());
-
- // Stop Move
- ExecuteCorrectStop();
- }
-
- private void PosButton_MouseDown(object sender, MouseEventArgs e)
- {
- logger.Info("Jog PosButton MouseDown");
- UpdateText("Moving at " + comboBox1.Text);
-
- // Start CW Jog
- rt_controller.StartRadioTelescopeAzimuthJog(speed, true);
- }
-
- private void PosButton_MouseUp(object sender, MouseEventArgs e)
- {
- logger.Info("Jog PosButton MouseUp");
- UpdateText("Manual Control for Radio Telescope " + rt_controller.RadioTelescope.Id.ToString());
-
- // Stop Move
- ExecuteCorrectStop();
- }
-
- private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
- {
- if(comboBox1.Text == "2 RPM")
- {
- logger.Info("Speed set to 2 RPM");
- speed = 333333;
- }
- else if(comboBox1.Text == "0.1 RPM")
- {
- logger.Info("Speed set to 0.1 RPM");
- speed = 16667;
- }
- else
- {
- logger.Info("Invalid Speed Selected");
- throw new Exception();
- }
- }
-
- private void ExecuteCorrectStop()
- {
- if (radioButton1.Checked)
- {
- logger.Info("Executed Controlled Stop");
- rt_controller.ExecuteRadioTelescopeControlledStop();
- }
- else if (radioButton2.Checked)
- {
- logger.Info("Executed Immediate Stop");
- rt_controller.ExecuteRadioTelescopeImmediateStop();
- }
- else
- {
- logger.Info("Invalid Stop Selected");
- throw new Exception();
- }
- }
-
- private void button1_Click(object sender, EventArgs e)
- {
- logger.Info("Move Relative Button Clicked");
- int pos = (int)numericUpDown1.Value * (int)((166 + (2.0 / 3.0)) * 200);
- rt_controller.ExecuteMoveRelativeAzimuth(RadioTelescopeAxisEnum.AZIMUTH,speed, pos);
- }
-
- private void timer1_Tick(object sender, EventArgs e)
- {
- Entities.Orientation currentOrienation = rt_controller.GetCurrentOrientation();
- SetActualAZText(currentOrienation.Azimuth.ToString("0.##"));
- SetActualELText(currentOrienation.Elevation.ToString("0.##"));
- }
-
- delegate void SetActualAZTextCallback(string text);
- private void SetActualAZText(string text)
- {
- // InvokeRequired required compares the thread ID of the
- // calling thread to the thread ID of the creating thread.
- // If these threads are different, it returns true.
- if (ActualAZTextBox.InvokeRequired)
- {
- //SetActualAZTextCallback d = new SetActualAZTextCallback(SetActualAZText);
- var d = new SetActualAZTextCallback(SetActualAZText);
- try
- {
- Invoke(d, new object[] { text });
-
- }
- catch (Exception e) { }
- }
- else
- {
- ActualAZTextBox.Text = text;
- }
- }
-
- delegate void SetActualELTextCallback(string text);
- private void SetActualELText(string text)
- {
- // InvokeRequired required compares the thread ID of the
- // calling thread to the thread ID of the creating thread.
- // If these threads are different, it returns true.
- if (ActualELTextBox.InvokeRequired)
- {
- //SetActualELTextCallback d = new SetActualELTextCallback(SetActualELText);
- var d = new SetActualELTextCallback(SetActualELText);
- try
- {
- Invoke(d, new object[] { text });
-
- }
- catch (Exception e) { }
- }
- else
- {
- ActualELTextBox.Text = text;
- }
- }
- }
-}
diff --git a/ControlRoomApplication/ControlRoomApplication/GUI/RTControlForm.cs b/ControlRoomApplication/ControlRoomApplication/GUI/RTControlForm.cs
new file mode 100644
index 00000000..eb99be60
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/GUI/RTControlForm.cs
@@ -0,0 +1,1144 @@
+using System;
+using System.ComponentModel;
+using System.IO;
+using System.Linq;
+using System.Threading;
+using System.Windows.Forms;
+using ControlRoomApplication.Controllers;
+using ControlRoomApplication.Database;
+using ControlRoomApplication.Entities;
+using ControlRoomApplication.Validation;
+using ControlRoomApplication.GUI.Data;
+using ControlRoomApplication.Util;
+using ControlRoomApplication.Constants;
+using ControlRoomApplication.Controllers.PLCCommunication.PLCDrivers.MCUManager.Enumerations;
+using ControlRoomApplication.Controllers.PLCCommunication.PLCDrivers.MCUManager;
+using System.Threading.Tasks;
+using ControlRoomApplication.Controllers.Communications;
+using ControlRoomApplication.GUI;
+
+namespace ControlRoomApplication.Main
+{
+ public partial class FreeControlForm : Form
+ {
+ public Appointment CurrentAppointment { get; set; }
+ public User ControlRoomUser { get; set; }
+ public Coordinate TargetCoordinate { get; set; }
+ public double Increment { get; set; }
+ public CoordinateCalculationController CoordCalc { set; get; }
+ public ControlRoom controlRoom { get; set; }
+ private RadioTelescopeController rtController { get; set; }
+ // private ControlRoomController MainControlRoomController { get; set; }
+ private Thread ControlRoomThread { get; set; }
+ public int rtId { get; set; }
+
+
+ private static int current_rt_id;
+ private static readonly log4net.ILog logger =
+ log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
+ public bool freeEditActive;
+ public bool manualControlActive;
+ public bool spectraEditActive;
+ bool manual_save_state;
+ bool save_state;
+ public SpectraCyberDCGainEnum DCGainInput;
+ public SpectraCyberIntegrationTimeEnum IntTimeInput;
+ public SpectraCyberBandwidthEnum BandwidthInput;
+ public bool acceptSettings = false;
+ public bool frequencyValid = false;
+ public bool offsetVoltValid = false;
+ public bool IFGainValid = false;
+ RTControlFormData formData;
+
+ public FreeControlForm(ControlRoom new_controlRoom, int new_rtId, RTControlFormData controlFormData)
+ {
+ InitializeComponent();
+ // Set ControlRoom
+ controlRoom = new_controlRoom;
+ // Set RT id
+ rtId = new_rtId;
+ // Make coordCalc
+ rtController = controlRoom.RadioTelescopeControllers.Find(x => x.RadioTelescope.Id == rtId);
+ CoordCalc = rtController.CoordinateController;
+ // Set increment
+ Increment = 1;
+ UpdateIncrementButtons();
+
+ // set form data object
+ formData = controlFormData;
+ formData.speed = 1;
+
+ // set form data
+ controlScriptsCombo.SelectedIndex = formData.controlScriptIndex;
+ scanTypeComboBox.SelectedIndex = formData.spectraCyberScanIndex;
+ frequency.Text = formData.frequency;
+ DCGain.SelectedIndex = formData.DCGainIndex;
+ integrationStepCombo.SelectedIndex = formData.integrationStepIndex;
+ speedTextBox.Text = formData.speed.ToString();
+ offsetVoltage.Text = formData.offsetVoltage;
+ IFGainVal.Text = formData.IFGain;
+ immediateRadioButton.Checked = formData.immediateStopBool;
+ ControlledButtonRadio.Checked = formData.controlledStopBool;
+ manual_save_state = formData.manualControlEnabled;
+ save_state = formData.freeControlEnabled;
+
+ ControlRoomUser = DatabaseOperations.GetControlRoomUser();
+
+ // Add free control appt
+ CurrentAppointment = new Appointment();
+ CurrentAppointment.start_time = DateTime.UtcNow.AddSeconds(5);
+ CurrentAppointment.end_time = DateTime.UtcNow.AddMinutes(15);
+ CurrentAppointment._Status = AppointmentStatusEnum.REQUESTED;
+ CurrentAppointment._Type = AppointmentTypeEnum.FREE_CONTROL;
+ CurrentAppointment._Priority = AppointmentPriorityEnum.MANUAL;
+ CurrentAppointment.SpectraCyberConfig = new SpectraCyberConfig(SpectraCyberModeTypeEnum.SPECTRAL);
+ CurrentAppointment.CelestialBody = new CelestialBody();
+ CurrentAppointment.CelestialBody.Coordinate = new Coordinate(0, 0);
+
+ CurrentAppointment.Orientation = rtController.GetCurrentOrientation();
+ CurrentAppointment.Telescope = controlRoom.RadioTelescopes.Find(x => x.Id == rtId);
+ CurrentAppointment.User = ControlRoomUser;
+
+ rtController.RadioTelescope.SpectraCyberController.Schedule.Mode = SpectraCyberScanScheduleMode.OFF;
+
+ DatabaseOperations.AddAppointment(CurrentAppointment);
+
+ //Calibrate Move
+ CalibrateMove();
+ runControlScriptButton.Enabled = false;
+
+ //Initialize Free control Box based on manual control
+ if (!save_state)
+ {
+ editButton.Text = "Edit Position";
+ if (manual_save_state)
+ {
+ editButton.BackColor = System.Drawing.Color.DarkGray;
+ freeControlGroupbox.BackColor = System.Drawing.Color.DarkGray;
+ editButton.Enabled = false;
+ }
+ else
+ {
+ editButton.BackColor = System.Drawing.Color.Red;
+ freeControlGroupbox.BackColor = System.Drawing.Color.DarkGray;
+ editButton.Enabled = true;
+ }
+
+ decIncGroupbox.BackColor = System.Drawing.Color.DarkGray;
+ RAIncGroupbox.BackColor = System.Drawing.Color.DarkGray;
+
+ }
+ else
+ {
+ editButton.Text = "Save Position";
+ editButton.BackColor = System.Drawing.Color.LimeGreen;
+ freeControlGroupbox.BackColor = System.Drawing.Color.Gainsboro;
+ decIncGroupbox.BackColor = System.Drawing.Color.Gray;
+ RAIncGroupbox.BackColor = System.Drawing.Color.Gray;
+ manualControlButton.Enabled = !formData.freeControlEnabled;
+ manualControlButton.BackColor = System.Drawing.Color.DarkGray;
+ }
+ PosDecButton.Enabled = formData.freeControlEnabled;
+ NegDecButton.Enabled = formData.freeControlEnabled;
+ PosRAButton.Enabled = formData.freeControlEnabled;
+ NegRAButton.Enabled = formData.freeControlEnabled;
+ oneForthButton.Enabled = formData.freeControlEnabled;
+ oneForthButtonDec.Enabled = formData.freeControlEnabled;
+ oneButton.Enabled = formData.freeControlEnabled;
+ oneButtonDec.Enabled = formData.freeControlEnabled;
+ fiveButton.Enabled = formData.freeControlEnabled;
+ fiveButtonDec.Enabled = formData.freeControlEnabled;
+ tenButton.Enabled = formData.freeControlEnabled;
+ tenButtonDec.Enabled = formData.freeControlEnabled;
+
+ //Initialize Manual control Box based on previous data (false by default)
+ if (!manual_save_state)
+ {
+ manualControlButton.Text = "Activate Manual Control";
+ // if free control is active, this button will be disabled. Gray it out if so
+ if (save_state)
+ {
+ manualControlButton.BackColor = System.Drawing.Color.DarkGray;
+ manualControlButton.Enabled = false;
+ }
+ else
+ {
+ manualControlButton.BackColor = System.Drawing.Color.Red;
+ manualControlButton.Enabled = true;
+ }
+ manualGroupBox.BackColor = System.Drawing.Color.DarkGray;
+ }
+ else if (manual_save_state)
+ {
+ manualControlButton.Text = "Deactivate Manual Control";
+ manualControlButton.BackColor = System.Drawing.Color.LimeGreen;
+ manualGroupBox.BackColor = System.Drawing.Color.Gainsboro;
+
+ }
+ plusElaButton.Enabled = formData.manualControlEnabled;
+ cwAzJogButton.Enabled = formData.manualControlEnabled;
+ ccwAzJogButton.Enabled = formData.manualControlEnabled;
+ subElaButton.Enabled = formData.manualControlEnabled;
+ ControlledButtonRadio.Enabled = formData.manualControlEnabled;
+ immediateRadioButton.Enabled = formData.manualControlEnabled;
+ speedTextBox.Enabled = formData.manualControlEnabled;
+ speedTrackBar.Enabled = formData.manualControlEnabled;
+ speedTrackBar.Value = 10;
+
+
+ //Initialize Start and Stop Scan buttons as disabled
+ spectraEditActive = true;
+ startScanButton.BackColor = System.Drawing.Color.DarkGray;
+ startScanButton.Enabled = false;
+ stopScanButton.BackColor = System.Drawing.Color.DarkGray;
+ stopScanButton.Enabled = false;
+
+ // finalize settings should be based on values in scan combo box
+ finalizeSettingsButton.Enabled = allScanInputsValid();
+
+ this.FormClosing += FreeControlForm_Closing;
+
+ logger.Info(Utilities.GetTimeStamp() + ": Radio Telescope Control Form Initalized");
+ }
+
+ void FreeControlForm_Closing(object sender, CancelEventArgs e)
+ {
+ logger.Info(Utilities.GetTimeStamp() + ": Radio Telescope Control Form Closing");
+ CurrentAppointment._Status = AppointmentStatusEnum.COMPLETED;
+ DatabaseOperations.UpdateAppointment(CurrentAppointment);
+
+ var threads = controlRoom.RTControllerManagementThreads.Where(t => t.RTController == rtController).ToList();
+
+ //Done in a new thread so the UI does not freeze while waiting for the move to finish
+ new Thread(() =>
+ {
+ threads[0].EndAppointment();
+ }).Start();
+
+
+ timer1.Enabled = false;
+ }
+
+ private void PosDecButton_Click(object sender, EventArgs e)
+ {
+ logger.Info(Utilities.GetTimeStamp() + ": Positive Declination Button Clicked");
+ Coordinate new_coord = new Coordinate(TargetCoordinate.RightAscension, TargetCoordinate.Declination + Increment);
+ Entities.Orientation test_orientation = CoordCalc.CoordinateToOrientation(new_coord, DateTime.UtcNow);
+ if(test_orientation.Azimuth > 0 && test_orientation.Elevation > 0)
+ {
+ TargetCoordinate = new_coord;
+ CoordMove();
+ }
+ else
+ {
+ errorLabel.Text = "Invalid Coordinate: orienation out of range";
+ }
+ }
+
+ private void NegDecButton_Click(object sender, EventArgs e)
+ {
+ logger.Info(Utilities.GetTimeStamp() + ": Negitive Declination Button Clicked");
+ Coordinate new_coord = new Coordinate(TargetCoordinate.RightAscension, TargetCoordinate.Declination - Increment);
+ Entities.Orientation test_orientation = CoordCalc.CoordinateToOrientation(new_coord, DateTime.UtcNow);
+ if (test_orientation.Azimuth > 0 && test_orientation.Elevation > 0)
+ {
+ TargetCoordinate = new_coord;
+ CoordMove();
+ }
+ else
+ {
+ errorLabel.Text = "Invalid Coordinate: orienation out of range";
+ }
+ }
+
+ private void NegRAButton_Click(object sender, EventArgs e)
+ {
+ logger.Info(Utilities.GetTimeStamp() + ": Negitive Right Ascension Button Clicked");
+ Coordinate new_coord = new Coordinate(TargetCoordinate.RightAscension - Increment, TargetCoordinate.Declination);
+ Entities.Orientation test_orientation = CoordCalc.CoordinateToOrientation(new_coord, DateTime.UtcNow);
+ if (test_orientation.Azimuth > 0 && test_orientation.Elevation > 0)
+ {
+ TargetCoordinate = new_coord;
+ CoordMove();
+ }
+ else
+ {
+ errorLabel.Text = "Invalid Coordinate: orienation out of range";
+ }
+ }
+
+ private void PosRAButton_Click(object sender, EventArgs e)
+ {
+ logger.Info(Utilities.GetTimeStamp() + ": Positive Right Ascension Button Clicked");
+ Coordinate new_coord = new Coordinate(TargetCoordinate.RightAscension + Increment, TargetCoordinate.Declination);
+ Entities.Orientation test_orientation = CoordCalc.CoordinateToOrientation(new_coord, DateTime.UtcNow);
+ if (test_orientation.Azimuth >= 0 && test_orientation.Elevation >= 0)
+ {
+ TargetCoordinate = new_coord;
+ CoordMove();
+ }
+ else
+ {
+ errorLabel.Text = "Invalid Coordinate: orienation out of range";
+ }
+ }
+
+ private void CalibrateButton_Click(object sender, EventArgs e)
+ {
+ logger.Info(Utilities.GetTimeStamp() + ": Calibrate Button Clicked");
+ CalibrateMove();
+ }
+
+ public void CalibrateMove()
+ {
+ logger.Info(Utilities.GetTimeStamp() + ": CalibrateMove ");
+ TargetCoordinate = CoordCalc.OrientationToCoordinate(CurrentAppointment.Orientation, DateTime.UtcNow);
+ UpdateText();
+ }
+
+ private void CoordMove()
+ {
+ logger.Info(Utilities.GetTimeStamp() + ": CoordMove ");
+ CurrentAppointment.Coordinates.Add(TargetCoordinate);
+ DatabaseOperations.UpdateAppointment(CurrentAppointment);
+ UpdateText();
+ }
+
+ private void UpdateText()
+ {
+ string RA = TargetCoordinate.RightAscension.ToString("0.##");
+ string Dec = TargetCoordinate.Declination.ToString("0.##");
+ logger.Info(Utilities.GetTimeStamp() + ": UpdateText, Target Coordinate = RA:" + RA + ", Dec:" + Dec);
+
+ TargetRATextBox.Text = RA;
+ TargetDecTextBox.Text = Dec;
+
+ errorLabel.Text = "Free Control for Radio Telescope " + rtId.ToString();
+ }
+
+ private void timer1_Tick(object sender, EventArgs e)
+ {
+ Entities.Orientation currentOrienation = rtController.GetCurrentOrientation();
+ Coordinate ConvertedPosition = CoordCalc.OrientationToCoordinate(currentOrienation, DateTime.UtcNow);
+
+ Utilities.WriteToGUIFromThread(this, () => {
+ label4.Text = String.Format("{0:N2}", currentOrienation.Azimuth);
+ label5.Text = String.Format("{0:N2}", currentOrienation.Elevation);
+
+ ActualRATextBox.Text = ConvertedPosition.RightAscension.ToString("0.##");
+ ActualDecTextBox.Text = ConvertedPosition.Declination.ToString("0.##");
+ });
+ }
+
+ private void oneForthButton_Click(object sender, EventArgs e)
+ {
+ logger.Info(Utilities.GetTimeStamp() + ": Increment = 0.25 Button Clicked");
+ Increment = 0.25;
+ UpdateIncrementButtons();
+ }
+
+ private void oneButton_Click(object sender, EventArgs e)
+ {
+ logger.Info(Utilities.GetTimeStamp() + ": Increment = 1 Button Clicked");
+ Increment = 1;
+ UpdateIncrementButtons();
+ }
+
+ private void fiveButton_Click(object sender, EventArgs e)
+ {
+ logger.Info(Utilities.GetTimeStamp() + ": Increment = 5 Button Clicked");
+ Increment = 5;
+ UpdateIncrementButtons();
+ }
+
+ private void tenButton_Click(object sender, EventArgs e)
+ {
+ logger.Info(Utilities.GetTimeStamp() + ": Increment = 10 Button Clicked");
+ Increment = 10;
+ UpdateIncrementButtons();
+ }
+
+ private void UpdateIncrementButtons()
+ {
+
+ switch (Increment)
+ {
+ case 0.25:
+ oneForthButton.BackColor = System.Drawing.Color.DarkGray;
+ break;
+ case 1:
+ oneButton.BackColor = System.Drawing.Color.DarkGray;
+ break;
+ case 5:
+ fiveButton.BackColor = System.Drawing.Color.DarkGray;
+ break;
+ case 10:
+ tenButton.BackColor = System.Drawing.Color.DarkGray;
+ break;
+ default:
+ throw new ArgumentException("Invalid Increment");
+ }
+ }
+
+ private void editButton_Click(object sender, EventArgs e)
+ {
+ logger.Info(Utilities.GetTimeStamp() + ": Edit Button Clicked");
+ save_state = !save_state;
+
+ formData.freeControlEnabled = save_state;
+ if (!save_state)
+ {
+ editButton.Text = "Edit Position";
+ editButton.BackColor = System.Drawing.Color.Red;
+ freeControlGroupbox.BackColor = System.Drawing.Color.DarkGray;
+ manualControlButton.BackColor = System.Drawing.Color.Red;
+ decIncGroupbox.BackColor = System.Drawing.Color.DarkGray;
+ RAIncGroupbox.BackColor = System.Drawing.Color.DarkGray;
+ double newRA;
+ double newDec;
+ double.TryParse(TargetRATextBox.Text, out newRA);
+ double.TryParse(TargetDecTextBox.Text, out newDec);
+ Coordinate new_coord = new Coordinate(newRA, newDec);
+ Entities.Orientation test_orientation = CoordCalc.CoordinateToOrientation(new_coord, DateTime.UtcNow);
+ if (test_orientation.Azimuth >= 0 && test_orientation.Elevation >= 0)
+ {
+ TargetCoordinate = new_coord;
+ CoordMove();
+ }
+ else
+ {
+ errorLabel.Text = "Invalid Coordinate: orienation out of range";
+ }
+ }
+ else
+ {
+ editButton.Text = "Save Position";
+ manualControlButton.BackColor = System.Drawing.Color.DarkGray;
+ editButton.BackColor = System.Drawing.Color.LimeGreen;
+ freeControlGroupbox.BackColor = System.Drawing.Color.Gainsboro;
+ decIncGroupbox.BackColor = System.Drawing.Color.Gray;
+ RAIncGroupbox.BackColor = System.Drawing.Color.Gray;
+ }
+
+ PosDecButton.Enabled = save_state;
+ NegDecButton.Enabled = save_state;
+ PosRAButton.Enabled = save_state;
+ NegRAButton.Enabled = save_state;
+ oneForthButton.Enabled = save_state;
+ oneForthButtonDec.Enabled = save_state;
+ oneButton.Enabled = save_state;
+ oneButtonDec.Enabled = save_state;
+ fiveButton.Enabled = save_state;
+ fiveButtonDec.Enabled = save_state;
+ tenButton.Enabled = save_state;
+ tenButtonDec.Enabled = save_state;
+ TargetRATextBox.ReadOnly = save_state;
+ TargetDecTextBox.ReadOnly = save_state;
+
+ manualControlButton.Enabled = !save_state;
+ }
+ //
+ private void manualControlButton_Click(object sender, EventArgs e)
+ {
+ logger.Info(Utilities.GetTimeStamp() + ": Activate Manual Control Clicked");
+ manual_save_state = !manual_save_state;
+ formData.manualControlEnabled = manual_save_state;
+
+ if (!manual_save_state)
+ {
+ manualControlButton.Text = "Activate Manual Control";
+ manualControlButton.BackColor = System.Drawing.Color.Red;
+ manualGroupBox.BackColor = System.Drawing.Color.DarkGray;
+ editButton.BackColor = System.Drawing.Color.Red;
+ }
+ else if(manual_save_state)
+ {
+ manualControlButton.Text = "Deactivate Manual Control";
+ manualControlButton.BackColor = System.Drawing.Color.LimeGreen;
+ manualGroupBox.BackColor = System.Drawing.Color.Gainsboro;
+ editButton.BackColor = System.Drawing.Color.DarkGray;
+
+ }
+ plusElaButton.Enabled = manual_save_state;
+ cwAzJogButton.Enabled = manual_save_state;
+ ccwAzJogButton.Enabled = manual_save_state;
+ subElaButton.Enabled = manual_save_state;
+ ControlledButtonRadio.Enabled = manual_save_state;
+ immediateRadioButton.Enabled = manual_save_state;
+ speedTextBox.Enabled = manual_save_state;
+ speedTrackBar.Enabled = manual_save_state;
+
+ editButton.Enabled = !manual_save_state;
+ }
+
+
+ //Run Script Button Functionality
+ //Case Depends on which script is currently selected
+ private async void runControlScript_Click(object sender, EventArgs e)
+ {
+ int index = controlScriptsCombo.SelectedIndex + 0;
+ string indexName = controlScriptsCombo.SelectedItem.ToString();
+
+ // We must run this async so it doesn't hold up the UI
+ await Task.Run(() => {
+ logger.Info($"{Utilities.GetTimeStamp()}: Starting script {indexName}.");
+
+ MovementResult movementResult = MovementResult.None;
+
+ switch (index)
+ {
+ case 1:
+ movementResult = rtController.MoveRadioTelescopeToOrientation(MiscellaneousConstants.Stow, MovementPriority.Manual);
+ break;
+
+ case 2:
+ movementResult = rtController.FullElevationMove(MovementPriority.Manual);
+ break;
+
+ case 3:
+ movementResult = rtController.MoveRadioTelescopeByXDegrees(new Entities.Orientation(360, 0), MovementPriority.Manual);
+ break;
+
+ case 4:
+ movementResult = rtController.MoveRadioTelescopeByXDegrees(new Entities.Orientation(-360, 0), MovementPriority.Manual);
+ break;
+
+ case 5:
+ movementResult = rtController.ThermalCalibrateRadioTelescope(MovementPriority.Manual);
+ break;
+
+ case 6:
+ movementResult = rtController.SnowDump(MovementPriority.Manual);
+ break;
+
+ case 7:
+ movementResult = rtController.HomeTelescope(MovementPriority.Manual);
+ break;
+
+ case 8:
+ // Create a new CustomOrientationInputDialog instance to allow the user to enter data
+
+ CustomOrientationInputDialog id = new CustomOrientationInputDialog(rtController.EnableSoftwareStops, rtController.RadioTelescope.teleType, rtController.RadioTelescope.maxElevationDegrees, rtController.RadioTelescope.minElevationDegrees);
+
+ Entities.Orientation currentOrientation = rtController.GetCurrentOrientation();
+
+ id.Text = "Custom Orientation Movement"; // Set the title of the input form
+
+ if (id.ShowDialog() == DialogResult.OK) // Use the data entered when the user clicks OK. (OK cannot be clicked unless the input is valid)
+ {
+ Entities.Orientation moveTo = new Entities.Orientation(id.AzimuthPos, id.ElevationPos);
+ movementResult = rtController.MoveRadioTelescopeToOrientation(moveTo, MovementPriority.Manual);
+ }
+
+ break;
+
+ case 9:
+ rtController.StartRadioTelescopeJog(1, RadioTelescopeDirectionEnum.ClockwiseOrNegative, RadioTelescopeAxisEnum.AZIMUTH);
+ MessageBox.Show("Currently spinning Azimuth. Press OK to stop spinning.", "Azimuth Moving");
+ ExecuteCorrectStop();
+ movementResult = MovementResult.Success;
+ break;
+
+ // Hardware movement script
+ case 10:
+ movementResult = rtController.ExecuteHardwareMovementScript(MovementPriority.Manual);
+ break;
+ default:
+ // Script does not exist
+ break;
+ }
+
+ if(movementResult == MovementResult.Success)
+ {
+ logger.Info($"{Utilities.GetTimeStamp()}: Successfully finished script {indexName}.");
+ }
+ else if (movementResult != MovementResult.None)
+ {
+ logger.Info($"{Utilities.GetTimeStamp()}: Script {indexName} FAILED with error message: {movementResult.ToString()}");
+ pushNotification.sendToAllAdmins("Script Failed", $"Script {indexName} FAILED with error message: {movementResult.ToString()}");
+ EmailNotifications.sendToAllAdmins("Script Failed", $"Script {indexName} FAILED with error message: {movementResult.ToString()}");
+ }
+ });
+ }
+
+ //Control Script combo box enables run button when a script has been selected
+ private void controlScriptsCombo_SelectedIndexChanged(object sender, EventArgs e)
+ {
+ if (controlScriptsCombo.SelectedIndex > 0)
+ {
+ runControlScriptButton.Enabled = true;
+ runControlScriptButton.BackColor = System.Drawing.Color.LimeGreen;
+ }
+ if(controlScriptsCombo.SelectedIndex == 0)
+ {
+ runControlScriptButton.Enabled = false;
+ runControlScriptButton.BackColor = System.Drawing.Color.Gray;
+ }
+
+ formData.controlScriptIndex = controlScriptsCombo.SelectedIndex;
+
+ }
+
+ ///
+ /// Functionality for when the STOP Telescope button is pressed. Creates a confirmation pop up box to prevent accidental presses of the stop button before sending any stop script.
+ ///
+ private void stopRT_click(object sender, EventArgs e)
+ {
+ DialogResult result = MessageBox.Show("Are you sure you want to stop the telescope?", "Telescope Stop Confirmation", MessageBoxButtons.YesNo);
+
+ if (result == DialogResult.Yes)
+ {
+ // Run the stop script for the telescope
+ rtController.RadioTelescope.PLCDriver.InterruptMovementAndWaitUntilStopped(true);
+ logger.Info($"{Utilities.GetTimeStamp()}: Telescope movement stopped.");
+ }
+ }
+
+ private void ccwAzJogButton_Down( object sender , MouseEventArgs e ) {
+ if (Validator.ValidateSpeedTextOnly(speedTextBox.Text))
+ {
+ double speed = Convert.ToDouble(speedTextBox.Text);
+ if (Validator.ValidateSpeed(speed))
+ {
+ // Start CW Jog
+ MovementResult result = rtController.StartRadioTelescopeJog(speed, RadioTelescopeDirectionEnum.CounterclockwiseOrPositive, RadioTelescopeAxisEnum.AZIMUTH);
+
+ if (result == MovementResult.Success)
+ logger.Info($"{Utilities.GetTimeStamp()}: Successfully started azimuth counterclockwise jog.");
+ else if (result == MovementResult.StoppingCurrentMove)
+ logger.Info($"{Utilities.GetTimeStamp()}: Stopping current movement. Please wait until that movement has finished ending and try to jog again.");
+ else if (result == MovementResult.AlreadyMoving)
+ logger.Info($"{Utilities.GetTimeStamp()}: Azimuth counterclockwise jog BLOCKED. Another manual script is already running.");
+ else
+ {
+ logger.Info($"{Utilities.GetTimeStamp()}: An error occurred trying to jog az counterclockwise: {result.ToString()}");
+ pushNotification.sendToAllAdmins("Jog Error", $"An error occurred trying to jog az counterclockwise: {result.ToString()}");
+ EmailNotifications.sendToAllAdmins("Jog Error", $"An error occurred trying to jog az counterclockwise: {result.ToString()}");
+ }
+ }
+ else
+ {
+ MessageBox.Show("Speed is not in valid range, 0.0-2.0 RPMs. Please try again");
+ }
+ }
+ else
+ {
+ MessageBox.Show("Invalid speed. Must be in RPMs between 0.0 and 2.0");
+ }
+ }
+
+ private void ccwAzJogButton_Up( object sender , MouseEventArgs e ) {
+ //Stop Move
+ ExecuteCorrectStop();
+ }
+
+ private void cwAzJogButton_Down(object sender, MouseEventArgs e)
+ {
+ if (Validator.ValidateSpeedTextOnly(speedTextBox.Text))
+ {
+ double speed = Convert.ToDouble(speedTextBox.Text);
+
+ if (Validator.ValidateSpeed(speed))
+ {
+ // Start CW Jog
+ MovementResult result = rtController.StartRadioTelescopeJog(speed, RadioTelescopeDirectionEnum.ClockwiseOrNegative, RadioTelescopeAxisEnum.AZIMUTH);
+
+ if (result == MovementResult.Success)
+ logger.Info($"{Utilities.GetTimeStamp()}: Successfully started azimuth clockwise jog.");
+ else if (result == MovementResult.StoppingCurrentMove)
+ logger.Info($"{Utilities.GetTimeStamp()}: Stopping current movement. Please wait until that movement has finished ending and try to jog again.");
+ else if (result == MovementResult.AlreadyMoving)
+ logger.Info($"{Utilities.GetTimeStamp()}: Azimuth clockwise jog BLOCKED. Another manual script is already running.");
+ else
+ {
+ logger.Info($"{Utilities.GetTimeStamp()}: An error occurred trying to jog az clockwise: {result.ToString()}");
+ pushNotification.sendToAllAdmins("Jog Error", $"An error occurred trying to jog az clockwise: {result.ToString()}");
+ EmailNotifications.sendToAllAdmins("Jog Error", $"An error occurred trying to jog az clockwise: {result.ToString()}");
+ }
+ }
+ else
+ {
+ MessageBox.Show("Speed is not in valid range, 0.0-2.0 RPMs. Please try again");
+ }
+ }
+ else
+ {
+ MessageBox.Show("Invalid speed. Must be in RPMs between 0.0 and 2.0");
+ }
+ }
+
+ private void cwAzJogButton_UP( object sender , MouseEventArgs e ) {
+ // Stop Move
+ ExecuteCorrectStop();
+ }
+
+ private void ExecuteCorrectStop()
+ {
+ MovementResult result = MovementResult.None;
+
+ if (ControlledButtonRadio.Checked)
+ {
+ result = rtController.ExecuteRadioTelescopeStopJog(MCUCommandType.ControlledStop);
+ formData.immediateStopBool = false;
+ formData.controlledStopBool = true;
+
+ if (result == MovementResult.Success)
+ logger.Info($"{Utilities.GetTimeStamp()}: Successfully stopped jog with a controlled stop.");
+ else
+ {
+ logger.Info($"{Utilities.GetTimeStamp()}: Controlled stop error: {result}");
+ }
+ }
+ else if (immediateRadioButton.Checked)
+ {
+ result = rtController.ExecuteRadioTelescopeStopJog(MCUCommandType.ImmediateStop);
+ formData.immediateStopBool = true;
+ formData.controlledStopBool = false;
+
+ if (result == MovementResult.Success)
+ logger.Info($"{Utilities.GetTimeStamp()}: Successfully stopped jog with an immediate stop.");
+ else
+ {
+ logger.Info($"{Utilities.GetTimeStamp()}: Immediate stop error: {result}");
+ }
+ }
+ else
+ {
+ logger.Info(Utilities.GetTimeStamp() + ": Invalid Stop Selected");
+ throw new Exception();
+ }
+
+ }
+
+ //This Button executes a system call that opens up the user interface documentation as a PDF
+ private void helpButton_click(object sender, EventArgs e)
+ {
+ string filename = Directory.GetCurrentDirectory() + "\\" + "UIDoc.pdf";
+ if (File.Exists(filename))
+ System.Diagnostics.Process.Start(filename);
+ }
+
+ private void plusElaButton_Down(object sender, MouseEventArgs e ){
+ if (Validator.ValidateSpeedTextOnly(speedTextBox.Text))
+ {
+ double speed = Convert.ToDouble(speedTextBox.Text);
+ if (Validator.ValidateSpeed(speed))
+ {
+ // Start CW Jog
+ MovementResult result = rtController.StartRadioTelescopeJog(speed, RadioTelescopeDirectionEnum.CounterclockwiseOrPositive, RadioTelescopeAxisEnum.ELEVATION);
+
+ if(result == MovementResult.Success)
+ logger.Info($"{Utilities.GetTimeStamp()}: Successfully started elevation positive jog.");
+ else if(result == MovementResult.StoppingCurrentMove)
+ logger.Info($"{Utilities.GetTimeStamp()}: Stopping current movement. Please wait until that movement has finished ending and try to jog again.");
+ else if(result == MovementResult.AlreadyMoving)
+ logger.Info($"{Utilities.GetTimeStamp()}: Elevation positive jog BLOCKED. Another manual script is already running.");
+ else
+ {
+ logger.Info($"{Utilities.GetTimeStamp()}: An error occurred trying to positive jog el: {result.ToString()}");
+ pushNotification.sendToAllAdmins("Jog Error", $"An error occurred trying to positive jog el: {result.ToString()}");
+ EmailNotifications.sendToAllAdmins("Jog Error", $"An error occurred trying to positive jog el: {result.ToString()}");
+ }
+ }
+ else
+ {
+ MessageBox.Show("Speed is not in valid range, 0.0-2.0 RPMs. Please try again");
+ }
+ }
+ else
+ {
+ MessageBox.Show("Invalid speed. Must be in RPMs between 0.0 and 2.0");
+ }
+ }
+
+ private void plusElaButton_Up( object sender , MouseEventArgs e ) {
+ // Stop Move
+ ExecuteCorrectStop();
+ }
+
+ private void subElaButton_Down(object sender, MouseEventArgs e ){
+ if (Validator.ValidateSpeedTextOnly(speedTextBox.Text))
+ {
+ double speed = Convert.ToDouble(speedTextBox.Text);
+ if (Validator.ValidateSpeed(speed))
+ {
+ // Start CW Jog
+ MovementResult result = rtController.StartRadioTelescopeJog(speed, RadioTelescopeDirectionEnum.ClockwiseOrNegative, RadioTelescopeAxisEnum.ELEVATION);
+
+ if (result == MovementResult.Success)
+ logger.Info($"{Utilities.GetTimeStamp()}: Successfully started elevation negative jog.");
+ else if (result == MovementResult.StoppingCurrentMove)
+ logger.Info($"{Utilities.GetTimeStamp()}: Stopping current movement. Please wait until that movement has finished ending and try to jog again.");
+ else if (result == MovementResult.AlreadyMoving)
+ logger.Info($"{Utilities.GetTimeStamp()}: Elevation negative jog BLOCKED. Another manual script is already running.");
+ else
+ {
+ logger.Info($"{Utilities.GetTimeStamp()}: An error occurred trying to negative jog el: {result.ToString()}");
+ pushNotification.sendToAllAdmins("Jog Error", $"An error occurred trying to negative jog el: {result.ToString()}");
+ EmailNotifications.sendToAllAdmins("Jog Error", $"An error occurred trying to negative jog el: {result.ToString()}");
+ }
+ }
+ else
+ {
+ MessageBox.Show("Speed is not in valid range, 0.0-2.0 RPMs. Please try again");
+ }
+ }
+ else
+ {
+ MessageBox.Show("Invalid speed. Must be in RPMs between 0.0 and 2.0");
+ }
+ }
+
+ private void subElaButton_Up( object sender , MouseEventArgs e ) {
+ // Stop Move
+ ExecuteCorrectStop();
+ }
+
+ private void finalizeSettings_Click(object sender, EventArgs e)
+ {
+ acceptSettings = !acceptSettings;
+ if (acceptSettings)
+ {
+ this.finalizeSettingsButton.Text = "Edit Settings";
+ }
+ else
+ {
+ this.finalizeSettingsButton.Text = "Finalize Settings";
+ }
+ logger.Info(Utilities.GetTimeStamp() + ": [SpectraCyberController] Finalize settings button has been clicked");
+
+
+ if (spectraEditActive)
+ {
+ scanTypeComboBox.BackColor = System.Drawing.Color.DarkGray;
+ scanTypeComboBox.Enabled = false;
+ integrationStepCombo.BackColor = System.Drawing.Color.DarkGray;
+ integrationStepCombo.Enabled = false;
+ offsetVoltage.BackColor = System.Drawing.Color.DarkGray;
+ offsetVoltage.Enabled = false;
+ frequency.BackColor = System.Drawing.Color.DarkGray;
+ frequency.Enabled = false;
+ DCGain.BackColor = System.Drawing.Color.DarkGray;
+ DCGain.Enabled = false;
+ IFGainVal.BackColor = System.Drawing.Color.DarkGray;
+ IFGainVal.Enabled = false;
+
+ startScanButton.BackColor = System.Drawing.Color.LimeGreen;
+ startScanButton.Enabled = true;
+
+ spectraEditActive = false;
+
+ int caseSwitch = DCGain.SelectedIndex;
+
+ switch (caseSwitch)
+ {
+ case 1:
+ DCGainInput = SpectraCyberDCGainEnum.X1;
+ break;
+ case 2:
+ DCGainInput = SpectraCyberDCGainEnum.X5;
+ break;
+ case 3:
+ DCGainInput = SpectraCyberDCGainEnum.X10;
+ break;
+ case 4:
+ DCGainInput = SpectraCyberDCGainEnum.X20;
+ break;
+ case 5:
+ DCGainInput = SpectraCyberDCGainEnum.X50;
+ break;
+ case 6:
+ DCGainInput = SpectraCyberDCGainEnum.X60;
+ break;
+ }
+
+ caseSwitch = integrationStepCombo.SelectedIndex;
+
+ switch (caseSwitch)
+ {
+ case 1:
+ IntTimeInput = SpectraCyberIntegrationTimeEnum.SHORT_TIME_SPAN;
+ break;
+ case 2:
+ IntTimeInput = SpectraCyberIntegrationTimeEnum.MID_TIME_SPAN;
+ break;
+ case 3:
+ IntTimeInput = SpectraCyberIntegrationTimeEnum.LONG_TIME_SPAN;
+ break;
+ }
+
+ }
+ else
+ {
+ scanTypeComboBox.BackColor = System.Drawing.Color.White;
+ scanTypeComboBox.Enabled = true;
+ integrationStepCombo.BackColor = System.Drawing.Color.White;
+ integrationStepCombo.Enabled = true;
+ offsetVoltage.BackColor = System.Drawing.Color.White;
+ offsetVoltage.Enabled = true;
+ frequency.BackColor = System.Drawing.Color.White;
+ frequency.Enabled = true;
+ DCGain.BackColor = System.Drawing.Color.White;
+ DCGain.Enabled = true;
+ IFGainVal.BackColor = System.Drawing.Color.White;
+ IFGainVal.Enabled = true;
+
+ startScanButton.BackColor = System.Drawing.Color.DarkGray;
+ startScanButton.Enabled = false;
+
+ spectraEditActive = true;
+ }
+ }
+
+ private void startScan_Click(object sender, EventArgs e)
+ {
+ logger.Info(Utilities.GetTimeStamp() + ": [SpectraCyberController] Start Scan button has been clicked");
+
+ int caseSwitch = scanTypeComboBox.SelectedIndex;
+
+ switch (caseSwitch)
+ {
+ case 1:
+ rtController.RadioTelescope.SpectraCyberController.SetSpectraCyberModeType(SpectraCyberModeTypeEnum.CONTINUUM);
+ rtController.RadioTelescope.SpectraCyberController.SetFrequency(Convert.ToDouble(frequency.Text));
+ rtController.RadioTelescope.SpectraCyberController.SetContinuumIntegrationTime(IntTimeInput);
+ rtController.RadioTelescope.SpectraCyberController.SetContinuumOffsetVoltage(Convert.ToDouble(offsetVoltage.Text));
+ rtController.RadioTelescope.SpectraCyberController.SetContGain(DCGainInput);
+ rtController.RadioTelescope.SpectraCyberController.SetSpectraCyberIFGain(Convert.ToDouble(IFGainVal.Text));
+ break;
+ case 2:
+ rtController.RadioTelescope.SpectraCyberController.SetSpectraCyberModeType(SpectraCyberModeTypeEnum.SPECTRAL);
+ rtController.RadioTelescope.SpectraCyberController.SetFrequency(Convert.ToDouble(frequency.Text));
+ rtController.RadioTelescope.SpectraCyberController.SetSpectralIntegrationTime(IntTimeInput);
+ rtController.RadioTelescope.SpectraCyberController.SetSpectralOffsetVoltage(Convert.ToDouble(offsetVoltage.Text));
+ rtController.RadioTelescope.SpectraCyberController.SetSpecGain(DCGainInput);
+ rtController.RadioTelescope.SpectraCyberController.SetSpectraCyberIFGain(Convert.ToDouble(IFGainVal.Text));
+ break;
+ }
+
+ finalizeSettingsButton.Enabled = false;
+
+ startScanButton.Enabled = false;
+ startScanButton.BackColor = System.Drawing.Color.DarkGray;
+
+ stopScanButton.Enabled = true;
+ stopScanButton.BackColor = System.Drawing.Color.Red;
+
+ rtController.RadioTelescope.SpectraCyberController.StartScan(CurrentAppointment);
+ logger.Info(Utilities.GetTimeStamp() + ": [SpectraCyberController] Scan has started");
+
+ }
+
+ private void stopScan_Click(object sender, EventArgs e)
+ {
+ if (rtController.RadioTelescope.SpectraCyberController.Schedule.Mode == SpectraCyberScanScheduleMode.OFF ||
+ rtController.RadioTelescope.SpectraCyberController.Schedule.Mode == SpectraCyberScanScheduleMode.UNKNOWN)
+ logger.Info(Utilities.GetTimeStamp() + ": [SpectraCyberController] There is no scan to stop");
+ else
+ {
+ rtController.RadioTelescope.SpectraCyberController.StopScan();
+ logger.Info(Utilities.GetTimeStamp() + ": [SpectraCyberController] Scan has stopped");
+ }
+
+ finalizeSettingsButton.Enabled = true;
+
+ startScanButton.Enabled = true;
+ startScanButton.BackColor = System.Drawing.Color.LimeGreen;
+
+ stopScanButton.Enabled = false;
+ stopScanButton.BackColor = System.Drawing.Color.DarkGray;
+
+ }
+
+ private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
+ {
+ if (integrationStepCombo.SelectedIndex == 0)
+ {
+ finalizeSettingsButton.Enabled = false;
+ }
+ if (allScanInputsValid())
+ {
+ finalizeSettingsButton.Enabled = true;
+ }
+ formData.integrationStepIndex = integrationStepCombo.SelectedIndex;
+
+ }
+
+ private void scanTypeComboBox_SelectedIndexChanged(object sender, EventArgs e)
+ {
+ if (scanTypeComboBox.SelectedIndex == 0)
+ {
+ finalizeSettingsButton.Enabled = false;
+ }
+ if (allScanInputsValid())
+ {
+ finalizeSettingsButton.Enabled = true;
+ }
+ formData.spectraCyberScanIndex = scanTypeComboBox.SelectedIndex;
+ }
+
+
+ private void DCGain_SelectedIndexChanged(object sender, EventArgs e)
+ {
+ if (DCGain.SelectedIndex == 0)
+ {
+ finalizeSettingsButton.Enabled = false;
+ }
+ if (allScanInputsValid())
+ {
+ finalizeSettingsButton.Enabled = true;
+ }
+ formData.DCGainIndex = DCGain.SelectedIndex;
+
+ }
+
+ private void frequency_TextChanged(object sender, EventArgs e)
+ {
+ frequencyValid = Validator.ValidateFrequency(frequency.Text);
+ if (!frequencyValid)
+ {
+ finalizeSettingsButton.Enabled = false;
+ frequency.BackColor = System.Drawing.Color.Yellow;
+ Utilities.WriteToGUIFromThread(this, () =>
+ {
+ this.frequencyToolTip.Show("Frequency must be a non-negative\n " +
+ "value, in kilohertz (>= 0 kHz)", lblFrequency);
+ });
+
+ }
+ else
+ {
+ frequency.BackColor = System.Drawing.Color.White;
+ Utilities.WriteToGUIFromThread(this, () =>
+ {
+ this.frequencyToolTip.Hide(lblFrequency);
+ });
+ }
+ if(allScanInputsValid())
+ {
+ finalizeSettingsButton.Enabled = true;
+ }
+ formData.frequency = frequency.Text;
+ }
+
+ private void offsetVoltage_TextChanged(object sender, EventArgs e)
+ {
+ offsetVoltValid = Validator.ValidateOffsetVoltage(offsetVoltage.Text);
+ if (!offsetVoltValid)
+ {
+ finalizeSettingsButton.Enabled = false;
+ offsetVoltage.BackColor = System.Drawing.Color.Yellow;
+ Utilities.WriteToGUIFromThread(this, () =>
+ {
+ this.offsetVoltageToolTip.Show("Offset voltage must be\n " +
+ "between 0 - 4.095 Volts", label12);
+ });
+
+ }
+ else
+ {
+ offsetVoltage.BackColor = System.Drawing.Color.White;
+ Utilities.WriteToGUIFromThread(this, () =>
+ {
+ this.offsetVoltageToolTip.Hide(label12);
+ });
+
+ }
+ if (allScanInputsValid())
+ {
+ finalizeSettingsButton.Enabled = true;
+ }
+ formData.offsetVoltage = offsetVoltage.Text;
+ }
+
+ private void IFGainVal_TextChanged(object sender, EventArgs e)
+ {
+ IFGainValid = Validator.ValidateIFGain(IFGainVal.Text);
+ if (!IFGainValid)
+ {
+ finalizeSettingsButton.Enabled = false;
+ IFGainVal.BackColor = System.Drawing.Color.Yellow;
+ Utilities.WriteToGUIFromThread(this, () =>
+ {
+ this.IFGainToolTip.Show("IFGain must be between\n " +
+ "10.00 and 25.75 decibles.", lblIFGain);
+ });
+
+ }
+ else
+ {
+ IFGainVal.BackColor = System.Drawing.Color.White;
+ Utilities.WriteToGUIFromThread(this, () =>
+ {
+ this.IFGainToolTip.Hide(lblIFGain);
+ });
+
+ }
+ if (allScanInputsValid())
+ {
+ finalizeSettingsButton.Enabled = true;
+ }
+ formData.IFGain = IFGainVal.Text;
+ }
+
+ private void speedTrackBar_Scroll(object sender, EventArgs e)
+ {
+ double actualSpeed = (double)speedTrackBar.Value / 10;
+ speedTextBox.Text = actualSpeed.ToString();
+ Utilities.WriteToGUIFromThread(this, () =>
+ {
+ formData.speed = Double.Parse(speedTextBox.Text);
+ });
+
+ }
+
+ private bool allScanInputsValid()
+ {
+ return (scanTypeComboBox.SelectedIndex != 0 && integrationStepCombo.SelectedIndex != 0 &&
+ DCGain.SelectedIndex != 0 && offsetVoltValid && IFGainValid && frequencyValid);
+
+ }
+
+ protected override void OnFormClosed(FormClosedEventArgs e)
+ {
+ if (rtController.RadioTelescope.SpectraCyberController.Schedule.Mode == SpectraCyberScanScheduleMode.OFF ||
+ rtController.RadioTelescope.SpectraCyberController.Schedule.Mode == SpectraCyberScanScheduleMode.UNKNOWN)
+ logger.Info(Utilities.GetTimeStamp() + ": [SpectraCyberController] There is no scan to stop");
+ else
+ {
+ rtController.RadioTelescope.SpectraCyberController.StopScan();
+ logger.Info(Utilities.GetTimeStamp() + ": [SpectraCyberController] Scan has stopped");
+ }
+ }
+
+ private void speedTextBox_TextChanged(object sender, EventArgs e)
+ {
+
+ }
+
+ ///
+ /// Enable/disable the telescope's software-stops when the check box is checked or unchecked
+ ///
+ private void SoftwareStopsCheckBox_CheckedChanged(object sender, EventArgs e)
+ {
+ if (!SoftwareStopsCheckBox.Checked)
+ {
+ DialogResult result = MessageBox.Show("Are you sure you want to disable software stops?", "Software-Stops Confirmation", MessageBoxButtons.YesNo);
+
+ if (result == DialogResult.Yes)
+ {
+ rtController.EnableSoftwareStops = false;
+ }
+ else
+ {
+ SoftwareStopsCheckBox.Checked = true;
+ rtController.EnableSoftwareStops = true;
+ }
+ }
+ else
+ {
+ rtController.EnableSoftwareStops = true;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/GUI/RTControlForm.designer.cs b/ControlRoomApplication/ControlRoomApplication/GUI/RTControlForm.designer.cs
new file mode 100644
index 00000000..cb3d0dea
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/GUI/RTControlForm.designer.cs
@@ -0,0 +1,1097 @@
+using System;
+
+namespace ControlRoomApplication.Main
+{
+ partial class FreeControlForm
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.components = new System.ComponentModel.Container();
+ this.PosDecButton = new System.Windows.Forms.Button();
+ this.NegDecButton = new System.Windows.Forms.Button();
+ this.NegRAButton = new System.Windows.Forms.Button();
+ this.PosRAButton = new System.Windows.Forms.Button();
+ this.ActualRATextBox = new System.Windows.Forms.TextBox();
+ this.ActualPositionLabel = new System.Windows.Forms.Label();
+ this.ActualRALabel = new System.Windows.Forms.Label();
+ this.ActualDecLabel = new System.Windows.Forms.Label();
+ this.TargetDecLabel = new System.Windows.Forms.Label();
+ this.TargetRALabel = new System.Windows.Forms.Label();
+ this.TargetPositionLabel = new System.Windows.Forms.Label();
+ this.TargetDecTextBox = new System.Windows.Forms.TextBox();
+ this.TargetRATextBox = new System.Windows.Forms.TextBox();
+ this.timer1 = new System.Windows.Forms.Timer(this.components);
+ this.RAIncGroupbox = new System.Windows.Forms.GroupBox();
+ this.tenButton = new System.Windows.Forms.Button();
+ this.fiveButton = new System.Windows.Forms.Button();
+ this.oneButton = new System.Windows.Forms.Button();
+ this.oneForthButton = new System.Windows.Forms.Button();
+ this.editButton = new System.Windows.Forms.Button();
+ this.errorLabel = new System.Windows.Forms.Label();
+ this.overRideGroupbox = new System.Windows.Forms.GroupBox();
+ this.SoftwareStopsCheckBox = new System.Windows.Forms.CheckBox();
+ this.label8 = new System.Windows.Forms.Label();
+ this.statusTextBox = new System.Windows.Forms.TextBox();
+ this.ActualDecTextBox = new System.Windows.Forms.TextBox();
+ this.decIncGroupbox = new System.Windows.Forms.GroupBox();
+ this.tenButtonDec = new System.Windows.Forms.Button();
+ this.fiveButtonDec = new System.Windows.Forms.Button();
+ this.oneButtonDec = new System.Windows.Forms.Button();
+ this.oneForthButtonDec = new System.Windows.Forms.Button();
+ this.freeControlGroupbox = new System.Windows.Forms.GroupBox();
+ this.stopRT = new System.Windows.Forms.Button();
+ this.controlScriptsCombo = new System.Windows.Forms.ComboBox();
+ this.groupBox4 = new System.Windows.Forms.GroupBox();
+ this.runControlScriptButton = new System.Windows.Forms.Button();
+ this.manualGroupBox = new System.Windows.Forms.GroupBox();
+ this.speedTrackBar = new System.Windows.Forms.TrackBar();
+ this.label4 = new System.Windows.Forms.Label();
+ this.label5 = new System.Windows.Forms.Label();
+ this.label3 = new System.Windows.Forms.Label();
+ this.manualControlButton = new System.Windows.Forms.Button();
+ this.immediateRadioButton = new System.Windows.Forms.RadioButton();
+ this.ControlledButtonRadio = new System.Windows.Forms.RadioButton();
+ this.speedTextBox = new System.Windows.Forms.TextBox();
+ this.label2 = new System.Windows.Forms.Label();
+ this.label1 = new System.Windows.Forms.Label();
+ this.ccwAzJogButton = new System.Windows.Forms.Button();
+ this.plusElaButton = new System.Windows.Forms.Button();
+ this.subElaButton = new System.Windows.Forms.Button();
+ this.cwAzJogButton = new System.Windows.Forms.Button();
+ this.button1 = new System.Windows.Forms.Button();
+ this.spectraCyberGroupBox = new System.Windows.Forms.GroupBox();
+ this.label12 = new System.Windows.Forms.Label();
+ this.integrationStepCombo = new System.Windows.Forms.ComboBox();
+ this.label10 = new System.Windows.Forms.Label();
+ this.IFGainVal = new System.Windows.Forms.TextBox();
+ this.lblIFGain = new System.Windows.Forms.Label();
+ this.finalizeSettingsButton = new System.Windows.Forms.Button();
+ this.DCGain = new System.Windows.Forms.ComboBox();
+ this.stopScanButton = new System.Windows.Forms.Button();
+ this.startScanButton = new System.Windows.Forms.Button();
+ this.frequency = new System.Windows.Forms.TextBox();
+ this.lblFrequency = new System.Windows.Forms.Label();
+ this.label9 = new System.Windows.Forms.Label();
+ this.offsetVoltage = new System.Windows.Forms.TextBox();
+ this.scanTypeComboBox = new System.Windows.Forms.ComboBox();
+ this.IFGainToolTip = new System.Windows.Forms.ToolTip(this.components);
+ this.frequencyToolTip = new System.Windows.Forms.ToolTip(this.components);
+ this.offsetVoltageToolTip = new System.Windows.Forms.ToolTip(this.components);
+ this.RAIncGroupbox.SuspendLayout();
+ this.overRideGroupbox.SuspendLayout();
+ this.decIncGroupbox.SuspendLayout();
+ this.freeControlGroupbox.SuspendLayout();
+ this.groupBox4.SuspendLayout();
+ this.manualGroupBox.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.speedTrackBar)).BeginInit();
+ this.spectraCyberGroupBox.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // PosDecButton
+ //
+ this.PosDecButton.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
+ this.PosDecButton.BackColor = System.Drawing.Color.DarkGray;
+ this.PosDecButton.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+ this.PosDecButton.Location = new System.Drawing.Point(297, 56);
+ this.PosDecButton.Name = "PosDecButton";
+ this.PosDecButton.Size = new System.Drawing.Size(40, 40);
+ this.PosDecButton.TabIndex = 0;
+ this.PosDecButton.Text = "+ Dec";
+ this.PosDecButton.UseVisualStyleBackColor = false;
+ this.PosDecButton.Click += new System.EventHandler(this.PosDecButton_Click);
+ //
+ // NegDecButton
+ //
+ this.NegDecButton.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
+ this.NegDecButton.BackColor = System.Drawing.Color.DarkGray;
+ this.NegDecButton.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+ this.NegDecButton.Location = new System.Drawing.Point(296, 151);
+ this.NegDecButton.Name = "NegDecButton";
+ this.NegDecButton.Size = new System.Drawing.Size(40, 40);
+ this.NegDecButton.TabIndex = 1;
+ this.NegDecButton.Text = "- Dec";
+ this.NegDecButton.UseVisualStyleBackColor = false;
+ this.NegDecButton.Click += new System.EventHandler(this.NegDecButton_Click);
+ //
+ // NegRAButton
+ //
+ this.NegRAButton.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
+ this.NegRAButton.BackColor = System.Drawing.Color.DarkGray;
+ this.NegRAButton.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+ this.NegRAButton.Location = new System.Drawing.Point(250, 105);
+ this.NegRAButton.Name = "NegRAButton";
+ this.NegRAButton.Size = new System.Drawing.Size(40, 40);
+ this.NegRAButton.TabIndex = 2;
+ this.NegRAButton.Text = "- RA";
+ this.NegRAButton.UseVisualStyleBackColor = false;
+ this.NegRAButton.Click += new System.EventHandler(this.NegRAButton_Click);
+ //
+ // PosRAButton
+ //
+ this.PosRAButton.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
+ this.PosRAButton.BackColor = System.Drawing.Color.DarkGray;
+ this.PosRAButton.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+ this.PosRAButton.Location = new System.Drawing.Point(341, 105);
+ this.PosRAButton.Name = "PosRAButton";
+ this.PosRAButton.Size = new System.Drawing.Size(40, 40);
+ this.PosRAButton.TabIndex = 3;
+ this.PosRAButton.Text = "+ RA";
+ this.PosRAButton.UseVisualStyleBackColor = false;
+ this.PosRAButton.Click += new System.EventHandler(this.PosRAButton_Click);
+ //
+ // ActualRATextBox
+ //
+ this.ActualRATextBox.Anchor = System.Windows.Forms.AnchorStyles.Left;
+ this.ActualRATextBox.Location = new System.Drawing.Point(154, 59);
+ this.ActualRATextBox.Name = "ActualRATextBox";
+ this.ActualRATextBox.ReadOnly = true;
+ this.ActualRATextBox.Size = new System.Drawing.Size(100, 20);
+ this.ActualRATextBox.TabIndex = 5;
+ //
+ // ActualPositionLabel
+ //
+ this.ActualPositionLabel.Anchor = System.Windows.Forms.AnchorStyles.Left;
+ this.ActualPositionLabel.AutoSize = true;
+ this.ActualPositionLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F);
+ this.ActualPositionLabel.Location = new System.Drawing.Point(146, 17);
+ this.ActualPositionLabel.Name = "ActualPositionLabel";
+ this.ActualPositionLabel.Size = new System.Drawing.Size(114, 20);
+ this.ActualPositionLabel.TabIndex = 7;
+ this.ActualPositionLabel.Text = "Actual Position";
+ //
+ // ActualRALabel
+ //
+ this.ActualRALabel.Anchor = System.Windows.Forms.AnchorStyles.Left;
+ this.ActualRALabel.AutoSize = true;
+ this.ActualRALabel.Location = new System.Drawing.Point(150, 41);
+ this.ActualRALabel.Name = "ActualRALabel";
+ this.ActualRALabel.Size = new System.Drawing.Size(84, 13);
+ this.ActualRALabel.TabIndex = 8;
+ this.ActualRALabel.Text = "Right Ascension";
+ //
+ // ActualDecLabel
+ //
+ this.ActualDecLabel.Anchor = System.Windows.Forms.AnchorStyles.Left;
+ this.ActualDecLabel.AutoSize = true;
+ this.ActualDecLabel.Location = new System.Drawing.Point(150, 87);
+ this.ActualDecLabel.Name = "ActualDecLabel";
+ this.ActualDecLabel.Size = new System.Drawing.Size(60, 13);
+ this.ActualDecLabel.TabIndex = 9;
+ this.ActualDecLabel.Text = "Declination";
+ //
+ // TargetDecLabel
+ //
+ this.TargetDecLabel.Anchor = System.Windows.Forms.AnchorStyles.Right;
+ this.TargetDecLabel.AutoSize = true;
+ this.TargetDecLabel.Location = new System.Drawing.Point(16, 87);
+ this.TargetDecLabel.Name = "TargetDecLabel";
+ this.TargetDecLabel.Size = new System.Drawing.Size(60, 13);
+ this.TargetDecLabel.TabIndex = 14;
+ this.TargetDecLabel.Text = "Declination";
+ //
+ // TargetRALabel
+ //
+ this.TargetRALabel.Anchor = System.Windows.Forms.AnchorStyles.Right;
+ this.TargetRALabel.AutoSize = true;
+ this.TargetRALabel.Location = new System.Drawing.Point(16, 41);
+ this.TargetRALabel.Name = "TargetRALabel";
+ this.TargetRALabel.Size = new System.Drawing.Size(84, 13);
+ this.TargetRALabel.TabIndex = 13;
+ this.TargetRALabel.Text = "Right Ascension";
+ //
+ // TargetPositionLabel
+ //
+ this.TargetPositionLabel.Anchor = System.Windows.Forms.AnchorStyles.Right;
+ this.TargetPositionLabel.AutoSize = true;
+ this.TargetPositionLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F);
+ this.TargetPositionLabel.Location = new System.Drawing.Point(12, 17);
+ this.TargetPositionLabel.Name = "TargetPositionLabel";
+ this.TargetPositionLabel.Size = new System.Drawing.Size(115, 20);
+ this.TargetPositionLabel.TabIndex = 12;
+ this.TargetPositionLabel.Text = "Target Position";
+ //
+ // TargetDecTextBox
+ //
+ this.TargetDecTextBox.Anchor = System.Windows.Forms.AnchorStyles.Right;
+ this.TargetDecTextBox.Location = new System.Drawing.Point(20, 104);
+ this.TargetDecTextBox.Name = "TargetDecTextBox";
+ this.TargetDecTextBox.ReadOnly = true;
+ this.TargetDecTextBox.Size = new System.Drawing.Size(100, 20);
+ this.TargetDecTextBox.TabIndex = 11;
+ //
+ // TargetRATextBox
+ //
+ this.TargetRATextBox.Anchor = System.Windows.Forms.AnchorStyles.Right;
+ this.TargetRATextBox.Location = new System.Drawing.Point(20, 59);
+ this.TargetRATextBox.Name = "TargetRATextBox";
+ this.TargetRATextBox.ReadOnly = true;
+ this.TargetRATextBox.Size = new System.Drawing.Size(100, 20);
+ this.TargetRATextBox.TabIndex = 10;
+ //
+ // timer1
+ //
+ this.timer1.Enabled = true;
+ this.timer1.Interval = 1000;
+ this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
+ //
+ // RAIncGroupbox
+ //
+ this.RAIncGroupbox.Anchor = System.Windows.Forms.AnchorStyles.Top;
+ this.RAIncGroupbox.BackColor = System.Drawing.Color.Gray;
+ this.RAIncGroupbox.Controls.Add(this.tenButton);
+ this.RAIncGroupbox.Controls.Add(this.fiveButton);
+ this.RAIncGroupbox.Controls.Add(this.oneButton);
+ this.RAIncGroupbox.Controls.Add(this.oneForthButton);
+ this.RAIncGroupbox.Location = new System.Drawing.Point(4, 45);
+ this.RAIncGroupbox.Margin = new System.Windows.Forms.Padding(2);
+ this.RAIncGroupbox.Name = "RAIncGroupbox";
+ this.RAIncGroupbox.Padding = new System.Windows.Forms.Padding(2);
+ this.RAIncGroupbox.Size = new System.Drawing.Size(188, 54);
+ this.RAIncGroupbox.TabIndex = 16;
+ this.RAIncGroupbox.TabStop = false;
+ this.RAIncGroupbox.Text = "Right Ascension Increment";
+ //
+ // tenButton
+ //
+ this.tenButton.BackColor = System.Drawing.Color.DarkGray;
+ this.tenButton.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+ this.tenButton.Location = new System.Drawing.Point(136, 15);
+ this.tenButton.Margin = new System.Windows.Forms.Padding(2);
+ this.tenButton.Name = "tenButton";
+ this.tenButton.Size = new System.Drawing.Size(40, 30);
+ this.tenButton.TabIndex = 3;
+ this.tenButton.Text = "10";
+ this.tenButton.UseVisualStyleBackColor = false;
+ this.tenButton.Click += new System.EventHandler(this.tenButton_Click);
+ //
+ // fiveButton
+ //
+ this.fiveButton.BackColor = System.Drawing.Color.DarkGray;
+ this.fiveButton.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+ this.fiveButton.Location = new System.Drawing.Point(93, 15);
+ this.fiveButton.Margin = new System.Windows.Forms.Padding(2);
+ this.fiveButton.Name = "fiveButton";
+ this.fiveButton.Size = new System.Drawing.Size(40, 30);
+ this.fiveButton.TabIndex = 2;
+ this.fiveButton.Text = "5";
+ this.fiveButton.UseVisualStyleBackColor = false;
+ this.fiveButton.Click += new System.EventHandler(this.fiveButton_Click);
+ //
+ // oneButton
+ //
+ this.oneButton.BackColor = System.Drawing.Color.DarkGray;
+ this.oneButton.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+ this.oneButton.Location = new System.Drawing.Point(49, 15);
+ this.oneButton.Margin = new System.Windows.Forms.Padding(2);
+ this.oneButton.Name = "oneButton";
+ this.oneButton.Size = new System.Drawing.Size(40, 30);
+ this.oneButton.TabIndex = 1;
+ this.oneButton.Text = "1";
+ this.oneButton.UseVisualStyleBackColor = false;
+ this.oneButton.Click += new System.EventHandler(this.oneButton_Click);
+ //
+ // oneForthButton
+ //
+ this.oneForthButton.BackColor = System.Drawing.Color.DarkGray;
+ this.oneForthButton.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+ this.oneForthButton.Location = new System.Drawing.Point(5, 15);
+ this.oneForthButton.Margin = new System.Windows.Forms.Padding(2);
+ this.oneForthButton.Name = "oneForthButton";
+ this.oneForthButton.Size = new System.Drawing.Size(40, 30);
+ this.oneForthButton.TabIndex = 0;
+ this.oneForthButton.Text = "0.25";
+ this.oneForthButton.UseVisualStyleBackColor = false;
+ this.oneForthButton.Click += new System.EventHandler(this.oneForthButton_Click);
+ //
+ // editButton
+ //
+ this.editButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+ this.editButton.BackColor = System.Drawing.Color.OrangeRed;
+ this.editButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
+ this.editButton.Location = new System.Drawing.Point(250, 10);
+ this.editButton.Name = "editButton";
+ this.editButton.Size = new System.Drawing.Size(131, 25);
+ this.editButton.TabIndex = 17;
+ this.editButton.Text = "Edit Position";
+ this.editButton.UseVisualStyleBackColor = false;
+ this.editButton.Click += new System.EventHandler(this.editButton_Click);
+ //
+ // errorLabel
+ //
+ this.errorLabel.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
+ this.errorLabel.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
+ this.errorLabel.ForeColor = System.Drawing.Color.Red;
+ this.errorLabel.Location = new System.Drawing.Point(335, 423);
+ this.errorLabel.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
+ this.errorLabel.Name = "errorLabel";
+ this.errorLabel.Size = new System.Drawing.Size(230, 19);
+ this.errorLabel.TabIndex = 18;
+ this.errorLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
+ //
+ // overRideGroupbox
+ //
+ this.overRideGroupbox.BackColor = System.Drawing.Color.Gainsboro;
+ this.overRideGroupbox.Controls.Add(this.stopRT);
+ this.overRideGroupbox.Controls.Add(this.SoftwareStopsCheckBox);
+ this.overRideGroupbox.Controls.Add(this.label8);
+ this.overRideGroupbox.Controls.Add(this.statusTextBox);
+ this.overRideGroupbox.Controls.Add(this.ActualRATextBox);
+ this.overRideGroupbox.Controls.Add(this.ActualDecTextBox);
+ this.overRideGroupbox.Controls.Add(this.ActualPositionLabel);
+ this.overRideGroupbox.Controls.Add(this.ActualRALabel);
+ this.overRideGroupbox.Controls.Add(this.ActualDecLabel);
+ this.overRideGroupbox.Controls.Add(this.TargetDecLabel);
+ this.overRideGroupbox.Controls.Add(this.TargetRATextBox);
+ this.overRideGroupbox.Controls.Add(this.TargetRALabel);
+ this.overRideGroupbox.Controls.Add(this.TargetDecTextBox);
+ this.overRideGroupbox.Controls.Add(this.TargetPositionLabel);
+ this.overRideGroupbox.Location = new System.Drawing.Point(12, 9);
+ this.overRideGroupbox.Name = "overRideGroupbox";
+ this.overRideGroupbox.Size = new System.Drawing.Size(279, 198);
+ this.overRideGroupbox.TabIndex = 19;
+ this.overRideGroupbox.TabStop = false;
+ this.overRideGroupbox.Text = "Position Information";
+ //
+ // stopRT
+ //
+ this.stopRT.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+ this.stopRT.BackColor = System.Drawing.Color.Red;
+ this.stopRT.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
+ this.stopRT.Location = new System.Drawing.Point(154, 159);
+ this.stopRT.Margin = new System.Windows.Forms.Padding(2);
+ this.stopRT.Name = "stopRT";
+ this.stopRT.Size = new System.Drawing.Size(100, 31);
+ this.stopRT.TabIndex = 38;
+ this.stopRT.Text = "STOP Telescope";
+ this.stopRT.UseVisualStyleBackColor = false;
+ this.stopRT.Click += new System.EventHandler(this.stopRT_click);
+ this.stopRT.Enabled = true;
+ //
+ // SoftwareStopsCheckBox
+ //
+ this.SoftwareStopsCheckBox.AutoSize = true;
+ this.SoftwareStopsCheckBox.Checked = true;
+ this.SoftwareStopsCheckBox.CheckState = System.Windows.Forms.CheckState.Checked;
+ this.SoftwareStopsCheckBox.Location = new System.Drawing.Point(16, 158);
+ this.SoftwareStopsCheckBox.Margin = new System.Windows.Forms.Padding(2);
+ this.SoftwareStopsCheckBox.Name = "SoftwareStopsCheckBox";
+ this.SoftwareStopsCheckBox.Size = new System.Drawing.Size(134, 17);
+ this.SoftwareStopsCheckBox.TabIndex = 17;
+ this.SoftwareStopsCheckBox.Text = "Enable Software Stops";
+ this.SoftwareStopsCheckBox.UseVisualStyleBackColor = true;
+ this.SoftwareStopsCheckBox.CheckedChanged += new System.EventHandler(this.SoftwareStopsCheckBox_CheckedChanged);
+ //
+ // label8
+ //
+ this.label8.AutoSize = true;
+ this.label8.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.label8.Location = new System.Drawing.Point(16, 134);
+ this.label8.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
+ this.label8.Name = "label8";
+ this.label8.Size = new System.Drawing.Size(121, 13);
+ this.label8.TabIndex = 16;
+ this.label8.Text = "Radio Telescope Status";
+ //
+ // statusTextBox
+ //
+ this.statusTextBox.Location = new System.Drawing.Point(154, 131);
+ this.statusTextBox.Margin = new System.Windows.Forms.Padding(2);
+ this.statusTextBox.Name = "statusTextBox";
+ this.statusTextBox.ReadOnly = true;
+ this.statusTextBox.Size = new System.Drawing.Size(102, 20);
+ this.statusTextBox.TabIndex = 15;
+ //
+ // ActualDecTextBox
+ //
+ this.ActualDecTextBox.Anchor = System.Windows.Forms.AnchorStyles.Left;
+ this.ActualDecTextBox.Location = new System.Drawing.Point(154, 104);
+ this.ActualDecTextBox.Margin = new System.Windows.Forms.Padding(2);
+ this.ActualDecTextBox.Name = "ActualDecTextBox";
+ this.ActualDecTextBox.ReadOnly = true;
+ this.ActualDecTextBox.Size = new System.Drawing.Size(76, 20);
+ this.ActualDecTextBox.TabIndex = 6;
+ //
+ // decIncGroupbox
+ //
+ this.decIncGroupbox.Anchor = System.Windows.Forms.AnchorStyles.Top;
+ this.decIncGroupbox.BackColor = System.Drawing.Color.Gray;
+ this.decIncGroupbox.Controls.Add(this.tenButtonDec);
+ this.decIncGroupbox.Controls.Add(this.fiveButtonDec);
+ this.decIncGroupbox.Controls.Add(this.oneButtonDec);
+ this.decIncGroupbox.Controls.Add(this.oneForthButtonDec);
+ this.decIncGroupbox.Location = new System.Drawing.Point(4, 104);
+ this.decIncGroupbox.Margin = new System.Windows.Forms.Padding(2);
+ this.decIncGroupbox.Name = "decIncGroupbox";
+ this.decIncGroupbox.Padding = new System.Windows.Forms.Padding(2);
+ this.decIncGroupbox.Size = new System.Drawing.Size(188, 56);
+ this.decIncGroupbox.TabIndex = 20;
+ this.decIncGroupbox.TabStop = false;
+ this.decIncGroupbox.Text = "Declanation Increment";
+ //
+ // tenButtonDec
+ //
+ this.tenButtonDec.BackColor = System.Drawing.Color.DarkGray;
+ this.tenButtonDec.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+ this.tenButtonDec.Location = new System.Drawing.Point(136, 15);
+ this.tenButtonDec.Margin = new System.Windows.Forms.Padding(2);
+ this.tenButtonDec.Name = "tenButtonDec";
+ this.tenButtonDec.Size = new System.Drawing.Size(40, 30);
+ this.tenButtonDec.TabIndex = 3;
+ this.tenButtonDec.Text = "10";
+ this.tenButtonDec.UseVisualStyleBackColor = false;
+ //
+ // fiveButtonDec
+ //
+ this.fiveButtonDec.BackColor = System.Drawing.Color.DarkGray;
+ this.fiveButtonDec.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+ this.fiveButtonDec.Location = new System.Drawing.Point(93, 15);
+ this.fiveButtonDec.Margin = new System.Windows.Forms.Padding(2);
+ this.fiveButtonDec.Name = "fiveButtonDec";
+ this.fiveButtonDec.Size = new System.Drawing.Size(40, 30);
+ this.fiveButtonDec.TabIndex = 2;
+ this.fiveButtonDec.Text = "5";
+ this.fiveButtonDec.UseVisualStyleBackColor = false;
+ //
+ // oneButtonDec
+ //
+ this.oneButtonDec.BackColor = System.Drawing.Color.DarkGray;
+ this.oneButtonDec.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+ this.oneButtonDec.Location = new System.Drawing.Point(49, 15);
+ this.oneButtonDec.Margin = new System.Windows.Forms.Padding(2);
+ this.oneButtonDec.Name = "oneButtonDec";
+ this.oneButtonDec.Size = new System.Drawing.Size(40, 30);
+ this.oneButtonDec.TabIndex = 1;
+ this.oneButtonDec.Text = "1";
+ this.oneButtonDec.UseVisualStyleBackColor = false;
+ //
+ // oneForthButtonDec
+ //
+ this.oneForthButtonDec.BackColor = System.Drawing.Color.DarkGray;
+ this.oneForthButtonDec.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+ this.oneForthButtonDec.Location = new System.Drawing.Point(5, 15);
+ this.oneForthButtonDec.Margin = new System.Windows.Forms.Padding(2);
+ this.oneForthButtonDec.Name = "oneForthButtonDec";
+ this.oneForthButtonDec.Size = new System.Drawing.Size(40, 30);
+ this.oneForthButtonDec.TabIndex = 0;
+ this.oneForthButtonDec.Text = "0.25";
+ this.oneForthButtonDec.UseVisualStyleBackColor = false;
+ //
+ // freeControlGroupbox
+ //
+ this.freeControlGroupbox.BackColor = System.Drawing.Color.Gainsboro;
+ this.freeControlGroupbox.Controls.Add(this.NegRAButton);
+ this.freeControlGroupbox.Controls.Add(this.PosDecButton);
+ this.freeControlGroupbox.Controls.Add(this.decIncGroupbox);
+ this.freeControlGroupbox.Controls.Add(this.NegDecButton);
+ this.freeControlGroupbox.Controls.Add(this.PosRAButton);
+ this.freeControlGroupbox.Controls.Add(this.RAIncGroupbox);
+ this.freeControlGroupbox.Controls.Add(this.editButton);
+ this.freeControlGroupbox.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+ this.freeControlGroupbox.Location = new System.Drawing.Point(12, 213);
+ this.freeControlGroupbox.Name = "freeControlGroupbox";
+ this.freeControlGroupbox.Size = new System.Drawing.Size(405, 201);
+ this.freeControlGroupbox.TabIndex = 22;
+ this.freeControlGroupbox.TabStop = false;
+ this.freeControlGroupbox.Text = "Edit Target Position";
+ //
+ // controlScriptsCombo
+ //
+ this.controlScriptsCombo.BackColor = System.Drawing.Color.DarkGray;
+ this.controlScriptsCombo.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.controlScriptsCombo.FormattingEnabled = true;
+ this.controlScriptsCombo.Items.AddRange(new object[] {
+ "Radio Telescope Control Scripts",
+ "Stow Telescope",
+ "Full Elevation",
+ "Full 360 Clockwise Rotation",
+ "Full 360 Counter-Clockwise Rotation",
+ "Thermal Calibration",
+ "Snow Dump",
+ "Home Telescope",
+ "Custom Orientation Movement",
+ "Endless Azimuth Rotation",
+ "Hardware Movement Script"});
+ this.controlScriptsCombo.Location = new System.Drawing.Point(4, 28);
+ this.controlScriptsCombo.Name = "controlScriptsCombo";
+ this.controlScriptsCombo.Size = new System.Drawing.Size(260, 21);
+ this.controlScriptsCombo.TabIndex = 23;
+ this.controlScriptsCombo.SelectedIndexChanged += new System.EventHandler(this.controlScriptsCombo_SelectedIndexChanged);
+ //
+ // groupBox4
+ //
+ this.groupBox4.BackColor = System.Drawing.Color.Gainsboro;
+ this.groupBox4.Controls.Add(this.runControlScriptButton);
+ this.groupBox4.Controls.Add(this.controlScriptsCombo);
+ this.groupBox4.Location = new System.Drawing.Point(296, 29);
+ this.groupBox4.Margin = new System.Windows.Forms.Padding(2);
+ this.groupBox4.Name = "groupBox4";
+ this.groupBox4.Padding = new System.Windows.Forms.Padding(2);
+ this.groupBox4.Size = new System.Drawing.Size(418, 65);
+ this.groupBox4.TabIndex = 24;
+ this.groupBox4.TabStop = false;
+ this.groupBox4.Text = "Control Scripts and Spectra";
+ //
+ // runControlScriptButton
+ //
+ this.runControlScriptButton.BackColor = System.Drawing.Color.DarkGray;
+ this.runControlScriptButton.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+ this.runControlScriptButton.Location = new System.Drawing.Point(288, 16);
+ this.runControlScriptButton.Margin = new System.Windows.Forms.Padding(2);
+ this.runControlScriptButton.Name = "runControlScriptButton";
+ this.runControlScriptButton.Size = new System.Drawing.Size(126, 33);
+ this.runControlScriptButton.TabIndex = 24;
+ this.runControlScriptButton.Text = "Run Script";
+ this.runControlScriptButton.UseVisualStyleBackColor = false;
+ this.runControlScriptButton.Click += new System.EventHandler(this.runControlScript_Click);
+ //
+ // manualGroupBox
+ //
+ this.manualGroupBox.BackColor = System.Drawing.Color.Gainsboro;
+ this.manualGroupBox.Controls.Add(this.speedTrackBar);
+ this.manualGroupBox.Controls.Add(this.label4);
+ this.manualGroupBox.Controls.Add(this.label5);
+ this.manualGroupBox.Controls.Add(this.label3);
+ this.manualGroupBox.Controls.Add(this.manualControlButton);
+ this.manualGroupBox.Controls.Add(this.immediateRadioButton);
+ this.manualGroupBox.Controls.Add(this.ControlledButtonRadio);
+ this.manualGroupBox.Controls.Add(this.speedTextBox);
+ this.manualGroupBox.Controls.Add(this.label2);
+ this.manualGroupBox.Controls.Add(this.label1);
+ this.manualGroupBox.Controls.Add(this.ccwAzJogButton);
+ this.manualGroupBox.Controls.Add(this.plusElaButton);
+ this.manualGroupBox.Controls.Add(this.subElaButton);
+ this.manualGroupBox.Controls.Add(this.cwAzJogButton);
+ this.manualGroupBox.Location = new System.Drawing.Point(423, 213);
+ this.manualGroupBox.Margin = new System.Windows.Forms.Padding(2);
+ this.manualGroupBox.Name = "manualGroupBox";
+ this.manualGroupBox.Padding = new System.Windows.Forms.Padding(2);
+ this.manualGroupBox.Size = new System.Drawing.Size(279, 201);
+ this.manualGroupBox.TabIndex = 25;
+ this.manualGroupBox.TabStop = false;
+ this.manualGroupBox.Text = "Manual Control";
+ //
+ // speedTrackBar
+ //
+ this.speedTrackBar.Location = new System.Drawing.Point(108, 145);
+ this.speedTrackBar.Maximum = 20;
+ this.speedTrackBar.Name = "speedTrackBar";
+ this.speedTrackBar.Size = new System.Drawing.Size(150, 45);
+ this.speedTrackBar.SmallChange = 3;
+ this.speedTrackBar.TabIndex = 20;
+ this.speedTrackBar.Scroll += new System.EventHandler(this.speedTrackBar_Scroll);
+ //
+ // label4
+ //
+ this.label4.AutoSize = true;
+ this.label4.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.label4.Location = new System.Drawing.Point(105, 79);
+ this.label4.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
+ this.label4.Name = "label4";
+ this.label4.Size = new System.Drawing.Size(22, 13);
+ this.label4.TabIndex = 28;
+ this.label4.Text = "0.0";
+ //
+ // label5
+ //
+ this.label5.AutoSize = true;
+ this.label5.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.label5.Location = new System.Drawing.Point(105, 60);
+ this.label5.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
+ this.label5.Name = "label5";
+ this.label5.Size = new System.Drawing.Size(22, 13);
+ this.label5.TabIndex = 27;
+ this.label5.Text = "0.0";
+ //
+ // label3
+ //
+ this.label3.AutoSize = true;
+ this.label3.Location = new System.Drawing.Point(6, 147);
+ this.label3.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
+ this.label3.Name = "label3";
+ this.label3.Size = new System.Drawing.Size(76, 13);
+ this.label3.TabIndex = 26;
+ this.label3.Text = "Speed (RPMs)";
+ //
+ // manualControlButton
+ //
+ this.manualControlButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+ this.manualControlButton.BackColor = System.Drawing.Color.OrangeRed;
+ this.manualControlButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
+ this.manualControlButton.Location = new System.Drawing.Point(15, 17);
+ this.manualControlButton.Margin = new System.Windows.Forms.Padding(2);
+ this.manualControlButton.Name = "manualControlButton";
+ this.manualControlButton.Size = new System.Drawing.Size(150, 28);
+ this.manualControlButton.TabIndex = 25;
+ this.manualControlButton.Text = "Activate Manual Control";
+ this.manualControlButton.UseVisualStyleBackColor = false;
+ this.manualControlButton.Click += new System.EventHandler(this.manualControlButton_Click);
+ //
+ // immediateRadioButton
+ //
+ this.immediateRadioButton.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
+ this.immediateRadioButton.AutoSize = true;
+ this.immediateRadioButton.Location = new System.Drawing.Point(9, 123);
+ this.immediateRadioButton.Margin = new System.Windows.Forms.Padding(2);
+ this.immediateRadioButton.Name = "immediateRadioButton";
+ this.immediateRadioButton.Size = new System.Drawing.Size(98, 17);
+ this.immediateRadioButton.TabIndex = 24;
+ this.immediateRadioButton.Text = "Immediate Stop";
+ this.immediateRadioButton.UseVisualStyleBackColor = true;
+ //
+ // ControlledButtonRadio
+ //
+ this.ControlledButtonRadio.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
+ this.ControlledButtonRadio.AutoSize = true;
+ this.ControlledButtonRadio.Checked = true;
+ this.ControlledButtonRadio.Location = new System.Drawing.Point(9, 104);
+ this.ControlledButtonRadio.Margin = new System.Windows.Forms.Padding(2);
+ this.ControlledButtonRadio.Name = "ControlledButtonRadio";
+ this.ControlledButtonRadio.Size = new System.Drawing.Size(97, 17);
+ this.ControlledButtonRadio.TabIndex = 23;
+ this.ControlledButtonRadio.TabStop = true;
+ this.ControlledButtonRadio.Text = "Controlled Stop";
+ this.ControlledButtonRadio.UseVisualStyleBackColor = true;
+ //
+ // speedTextBox
+ //
+ this.speedTextBox.Anchor = System.Windows.Forms.AnchorStyles.Left;
+ this.speedTextBox.Location = new System.Drawing.Point(9, 162);
+ this.speedTextBox.Margin = new System.Windows.Forms.Padding(2);
+ this.speedTextBox.Name = "speedTextBox";
+ this.speedTextBox.ReadOnly = true;
+ this.speedTextBox.Size = new System.Drawing.Size(69, 20);
+ this.speedTextBox.TabIndex = 10;
+ this.speedTextBox.TextChanged += new System.EventHandler(this.speedTextBox_TextChanged);
+ //
+ // label2
+ //
+ this.label2.AutoSize = true;
+ this.label2.Location = new System.Drawing.Point(6, 80);
+ this.label2.Name = "label2";
+ this.label2.Size = new System.Drawing.Size(87, 13);
+ this.label2.TabIndex = 9;
+ this.label2.Text = "Current Azimuth: ";
+ //
+ // label1
+ //
+ this.label1.AutoSize = true;
+ this.label1.Location = new System.Drawing.Point(6, 60);
+ this.label1.Name = "label1";
+ this.label1.Size = new System.Drawing.Size(94, 13);
+ this.label1.TabIndex = 8;
+ this.label1.Text = "Current Elevation: ";
+ //
+ // ccwAzJogButton
+ //
+ this.ccwAzJogButton.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
+ this.ccwAzJogButton.BackColor = System.Drawing.Color.DarkGray;
+ this.ccwAzJogButton.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+ this.ccwAzJogButton.Location = new System.Drawing.Point(150, 54);
+ this.ccwAzJogButton.Margin = new System.Windows.Forms.Padding(2);
+ this.ccwAzJogButton.Name = "ccwAzJogButton";
+ this.ccwAzJogButton.Size = new System.Drawing.Size(40, 40);
+ this.ccwAzJogButton.TabIndex = 6;
+ this.ccwAzJogButton.Text = "CCW Jog";
+ this.ccwAzJogButton.UseVisualStyleBackColor = false;
+ this.ccwAzJogButton.MouseDown += new System.Windows.Forms.MouseEventHandler(this.ccwAzJogButton_Down);
+ this.ccwAzJogButton.MouseUp += new System.Windows.Forms.MouseEventHandler(this.ccwAzJogButton_Up);
+ //
+ // plusElaButton
+ //
+ this.plusElaButton.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
+ this.plusElaButton.BackColor = System.Drawing.Color.DarkGray;
+ this.plusElaButton.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+ this.plusElaButton.Location = new System.Drawing.Point(190, 10);
+ this.plusElaButton.Margin = new System.Windows.Forms.Padding(2);
+ this.plusElaButton.Name = "plusElaButton";
+ this.plusElaButton.Size = new System.Drawing.Size(40, 40);
+ this.plusElaButton.TabIndex = 4;
+ this.plusElaButton.Text = "+ Ela";
+ this.plusElaButton.UseVisualStyleBackColor = false;
+ this.plusElaButton.MouseDown += new System.Windows.Forms.MouseEventHandler(this.plusElaButton_Down);
+ this.plusElaButton.MouseUp += new System.Windows.Forms.MouseEventHandler(this.plusElaButton_Up);
+ //
+ // subElaButton
+ //
+ this.subElaButton.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
+ this.subElaButton.BackColor = System.Drawing.Color.DarkGray;
+ this.subElaButton.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+ this.subElaButton.Location = new System.Drawing.Point(190, 100);
+ this.subElaButton.Margin = new System.Windows.Forms.Padding(2);
+ this.subElaButton.Name = "subElaButton";
+ this.subElaButton.Size = new System.Drawing.Size(40, 40);
+ this.subElaButton.TabIndex = 5;
+ this.subElaButton.Text = "- Ela";
+ this.subElaButton.UseVisualStyleBackColor = false;
+ this.subElaButton.MouseDown += new System.Windows.Forms.MouseEventHandler(this.subElaButton_Down);
+ this.subElaButton.MouseUp += new System.Windows.Forms.MouseEventHandler(this.subElaButton_Up);
+ //
+ // cwAzJogButton
+ //
+ this.cwAzJogButton.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
+ this.cwAzJogButton.BackColor = System.Drawing.Color.DarkGray;
+ this.cwAzJogButton.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+ this.cwAzJogButton.Location = new System.Drawing.Point(230, 54);
+ this.cwAzJogButton.Margin = new System.Windows.Forms.Padding(2);
+ this.cwAzJogButton.Name = "cwAzJogButton";
+ this.cwAzJogButton.Size = new System.Drawing.Size(40, 40);
+ this.cwAzJogButton.TabIndex = 7;
+ this.cwAzJogButton.Text = "CW Jog";
+ this.cwAzJogButton.UseVisualStyleBackColor = false;
+ this.cwAzJogButton.MouseDown += new System.Windows.Forms.MouseEventHandler(this.cwAzJogButton_Down);
+ this.cwAzJogButton.MouseUp += new System.Windows.Forms.MouseEventHandler(this.cwAzJogButton_UP);
+ //
+ // button1
+ //
+ this.button1.BackColor = System.Drawing.Color.Gainsboro;
+ this.button1.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
+ this.button1.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.button1.ForeColor = System.Drawing.SystemColors.ControlText;
+ this.button1.Location = new System.Drawing.Point(692, 2);
+ this.button1.Margin = new System.Windows.Forms.Padding(2);
+ this.button1.Name = "button1";
+ this.button1.Size = new System.Drawing.Size(22, 23);
+ this.button1.TabIndex = 26;
+ this.button1.Text = "?";
+ this.button1.UseVisualStyleBackColor = false;
+ this.button1.Click += new System.EventHandler(this.helpButton_click);
+ //
+ // spectraCyberGroupBox
+ //
+ this.spectraCyberGroupBox.BackColor = System.Drawing.Color.Gainsboro;
+ this.spectraCyberGroupBox.Controls.Add(this.label12);
+ this.spectraCyberGroupBox.Controls.Add(this.integrationStepCombo);
+ this.spectraCyberGroupBox.Controls.Add(this.label10);
+ this.spectraCyberGroupBox.Controls.Add(this.IFGainVal);
+ this.spectraCyberGroupBox.Controls.Add(this.lblIFGain);
+ this.spectraCyberGroupBox.Controls.Add(this.finalizeSettingsButton);
+ this.spectraCyberGroupBox.Controls.Add(this.DCGain);
+ this.spectraCyberGroupBox.Controls.Add(this.stopScanButton);
+ this.spectraCyberGroupBox.Controls.Add(this.startScanButton);
+ this.spectraCyberGroupBox.Controls.Add(this.frequency);
+ this.spectraCyberGroupBox.Controls.Add(this.lblFrequency);
+ this.spectraCyberGroupBox.Controls.Add(this.label9);
+ this.spectraCyberGroupBox.Controls.Add(this.offsetVoltage);
+ this.spectraCyberGroupBox.Controls.Add(this.scanTypeComboBox);
+ this.spectraCyberGroupBox.Location = new System.Drawing.Point(296, 111);
+ this.spectraCyberGroupBox.Margin = new System.Windows.Forms.Padding(2);
+ this.spectraCyberGroupBox.Name = "spectraCyberGroupBox";
+ this.spectraCyberGroupBox.Padding = new System.Windows.Forms.Padding(2);
+ this.spectraCyberGroupBox.Size = new System.Drawing.Size(418, 84);
+ this.spectraCyberGroupBox.TabIndex = 29;
+ this.spectraCyberGroupBox.TabStop = false;
+ this.spectraCyberGroupBox.Text = "Spectra Cyber";
+ //
+ // label12
+ //
+ this.label12.Anchor = System.Windows.Forms.AnchorStyles.Right;
+ this.label12.AutoSize = true;
+ this.label12.Location = new System.Drawing.Point(133, 43);
+ this.label12.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
+ this.label12.Name = "label12";
+ this.label12.Size = new System.Drawing.Size(74, 13);
+ this.label12.TabIndex = 26;
+ this.label12.Text = "Offset Voltage";
+ //
+ // integrationStepCombo
+ //
+ this.integrationStepCombo.BackColor = System.Drawing.Color.DarkGray;
+ this.integrationStepCombo.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.integrationStepCombo.FormattingEnabled = true;
+ this.integrationStepCombo.Items.AddRange(new object[] {
+ "Int Step",
+ "0.3",
+ "0.5(S)/1.00(C) ",
+ "1.00(S)/10.00(C)"});
+ this.integrationStepCombo.Location = new System.Drawing.Point(215, 56);
+ this.integrationStepCombo.Margin = new System.Windows.Forms.Padding(2);
+ this.integrationStepCombo.MaxDropDownItems = 6;
+ this.integrationStepCombo.Name = "integrationStepCombo";
+ this.integrationStepCombo.Size = new System.Drawing.Size(79, 21);
+ this.integrationStepCombo.TabIndex = 44;
+ this.integrationStepCombo.SelectedIndexChanged += new System.EventHandler(this.comboBox1_SelectedIndexChanged);
+ //
+ // label10
+ //
+ this.label10.Anchor = System.Windows.Forms.AnchorStyles.Right;
+ this.label10.AutoSize = true;
+ this.label10.Location = new System.Drawing.Point(0, 41);
+ this.label10.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
+ this.label10.Name = "label10";
+ this.label10.Size = new System.Drawing.Size(66, 13);
+ this.label10.TabIndex = 43;
+ this.label10.Text = "DCGain (dB)";
+ //
+ // IFGainVal
+ //
+ this.IFGainVal.Anchor = System.Windows.Forms.AnchorStyles.Left;
+ this.IFGainVal.Location = new System.Drawing.Point(77, 57);
+ this.IFGainVal.Margin = new System.Windows.Forms.Padding(2);
+ this.IFGainVal.Name = "IFGainVal";
+ this.IFGainVal.Size = new System.Drawing.Size(44, 20);
+ this.IFGainVal.TabIndex = 42;
+ this.IFGainVal.TextChanged += new System.EventHandler(this.IFGainVal_TextChanged);
+ //
+ // lblIFGain
+ //
+ this.lblIFGain.Anchor = System.Windows.Forms.AnchorStyles.Right;
+ this.lblIFGain.AutoSize = true;
+ this.lblIFGain.Location = new System.Drawing.Point(74, 43);
+ this.lblIFGain.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
+ this.lblIFGain.Name = "lblIFGain";
+ this.lblIFGain.Size = new System.Drawing.Size(60, 13);
+ this.lblIFGain.TabIndex = 41;
+ this.lblIFGain.Text = "IFGain (dB)";
+ //
+ // finalizeSettingsButton
+ //
+ this.finalizeSettingsButton.BackColor = System.Drawing.Color.DarkGray;
+ this.finalizeSettingsButton.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+ this.finalizeSettingsButton.Location = new System.Drawing.Point(309, 10);
+ this.finalizeSettingsButton.Margin = new System.Windows.Forms.Padding(2);
+ this.finalizeSettingsButton.Name = "finalizeSettingsButton";
+ this.finalizeSettingsButton.Size = new System.Drawing.Size(97, 27);
+ this.finalizeSettingsButton.TabIndex = 40;
+ this.finalizeSettingsButton.Text = "Finalize Settings";
+ this.finalizeSettingsButton.UseVisualStyleBackColor = false;
+ this.finalizeSettingsButton.Click += new System.EventHandler(this.finalizeSettings_Click);
+ //
+ // DCGain
+ //
+ this.DCGain.BackColor = System.Drawing.Color.DarkGray;
+ this.DCGain.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.DCGain.FormattingEnabled = true;
+ this.DCGain.Items.AddRange(new object[] {
+ "Gain",
+ "x1",
+ "X5",
+ "X10",
+ "X20",
+ "X50",
+ "X60"});
+ this.DCGain.Location = new System.Drawing.Point(4, 56);
+ this.DCGain.Margin = new System.Windows.Forms.Padding(2);
+ this.DCGain.MaxDropDownItems = 6;
+ this.DCGain.Name = "DCGain";
+ this.DCGain.Size = new System.Drawing.Size(57, 21);
+ this.DCGain.TabIndex = 39;
+ this.DCGain.SelectedIndexChanged += new System.EventHandler(this.DCGain_SelectedIndexChanged);
+ //
+ // stopScanButton
+ //
+ this.stopScanButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+ this.stopScanButton.BackColor = System.Drawing.Color.OrangeRed;
+ this.stopScanButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
+ this.stopScanButton.Location = new System.Drawing.Point(361, 44);
+ this.stopScanButton.Margin = new System.Windows.Forms.Padding(2);
+ this.stopScanButton.Name = "stopScanButton";
+ this.stopScanButton.Size = new System.Drawing.Size(45, 36);
+ this.stopScanButton.TabIndex = 37;
+ this.stopScanButton.Text = "Stop Scan";
+ this.stopScanButton.UseVisualStyleBackColor = false;
+ this.stopScanButton.Click += new System.EventHandler(this.stopScan_Click);
+ //
+ // startScanButton
+ //
+ this.startScanButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+ this.startScanButton.BackColor = System.Drawing.Color.LimeGreen;
+ this.startScanButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
+ this.startScanButton.Location = new System.Drawing.Point(309, 44);
+ this.startScanButton.Margin = new System.Windows.Forms.Padding(2);
+ this.startScanButton.Name = "startScanButton";
+ this.startScanButton.Size = new System.Drawing.Size(48, 36);
+ this.startScanButton.TabIndex = 36;
+ this.startScanButton.Text = "Start Scan";
+ this.startScanButton.UseVisualStyleBackColor = false;
+ this.startScanButton.Click += new System.EventHandler(this.startScan_Click);
+ //
+ // frequency
+ //
+ this.frequency.Anchor = System.Windows.Forms.AnchorStyles.Left;
+ this.frequency.Location = new System.Drawing.Point(158, 18);
+ this.frequency.Margin = new System.Windows.Forms.Padding(2);
+ this.frequency.Name = "frequency";
+ this.frequency.Size = new System.Drawing.Size(76, 20);
+ this.frequency.TabIndex = 35;
+ this.frequency.TextChanged += new System.EventHandler(this.frequency_TextChanged);
+ //
+ // lblFrequency
+ //
+ this.lblFrequency.Anchor = System.Windows.Forms.AnchorStyles.Right;
+ this.lblFrequency.AutoSize = true;
+ this.lblFrequency.Location = new System.Drawing.Point(155, 0);
+ this.lblFrequency.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
+ this.lblFrequency.Name = "lblFrequency";
+ this.lblFrequency.Size = new System.Drawing.Size(85, 13);
+ this.lblFrequency.TabIndex = 34;
+ this.lblFrequency.Text = "Frequency (kHz)";
+ //
+ // label9
+ //
+ this.label9.Anchor = System.Windows.Forms.AnchorStyles.Right;
+ this.label9.AutoSize = true;
+ this.label9.Location = new System.Drawing.Point(212, 44);
+ this.label9.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
+ this.label9.Name = "label9";
+ this.label9.Size = new System.Drawing.Size(82, 13);
+ this.label9.TabIndex = 32;
+ this.label9.Text = "Integration Step";
+ //
+ // offsetVoltage
+ //
+ this.offsetVoltage.Anchor = System.Windows.Forms.AnchorStyles.Left;
+ this.offsetVoltage.Location = new System.Drawing.Point(136, 57);
+ this.offsetVoltage.Margin = new System.Windows.Forms.Padding(2);
+ this.offsetVoltage.Name = "offsetVoltage";
+ this.offsetVoltage.Size = new System.Drawing.Size(44, 20);
+ this.offsetVoltage.TabIndex = 27;
+ this.offsetVoltage.TextChanged += new System.EventHandler(this.offsetVoltage_TextChanged);
+ //
+ // scanTypeComboBox
+ //
+ this.scanTypeComboBox.BackColor = System.Drawing.Color.DarkGray;
+ this.scanTypeComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.scanTypeComboBox.FormattingEnabled = true;
+ this.scanTypeComboBox.Items.AddRange(new object[] {
+ "Scan Type",
+ "Continuum",
+ "Spectral"});
+ this.scanTypeComboBox.Location = new System.Drawing.Point(4, 18);
+ this.scanTypeComboBox.Margin = new System.Windows.Forms.Padding(2);
+ this.scanTypeComboBox.MaxDropDownItems = 2;
+ this.scanTypeComboBox.Name = "scanTypeComboBox";
+ this.scanTypeComboBox.Size = new System.Drawing.Size(83, 21);
+ this.scanTypeComboBox.TabIndex = 25;
+ this.scanTypeComboBox.SelectedIndexChanged += new System.EventHandler(this.scanTypeComboBox_SelectedIndexChanged);
+ //
+ // FreeControlForm
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.BackColor = System.Drawing.Color.Gray;
+ this.ClientSize = new System.Drawing.Size(725, 439);
+ this.Controls.Add(this.spectraCyberGroupBox);
+ this.Controls.Add(this.button1);
+ this.Controls.Add(this.manualGroupBox);
+ this.Controls.Add(this.groupBox4);
+ this.Controls.Add(this.freeControlGroupbox);
+ this.Controls.Add(this.overRideGroupbox);
+ this.Controls.Add(this.errorLabel);
+ this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
+ this.MinimumSize = new System.Drawing.Size(600, 476);
+ this.Name = "FreeControlForm";
+ this.Text = "Control Form";
+ this.RAIncGroupbox.ResumeLayout(false);
+ this.overRideGroupbox.ResumeLayout(false);
+ this.overRideGroupbox.PerformLayout();
+ this.decIncGroupbox.ResumeLayout(false);
+ this.freeControlGroupbox.ResumeLayout(false);
+ this.groupBox4.ResumeLayout(false);
+ this.manualGroupBox.ResumeLayout(false);
+ this.manualGroupBox.PerformLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.speedTrackBar)).EndInit();
+ this.spectraCyberGroupBox.ResumeLayout(false);
+ this.spectraCyberGroupBox.PerformLayout();
+ this.ResumeLayout(false);
+
+ }
+
+
+ #endregion
+
+ private System.Windows.Forms.Button PosDecButton;
+ private System.Windows.Forms.Button NegDecButton;
+ private System.Windows.Forms.Button NegRAButton;
+ private System.Windows.Forms.Button PosRAButton;
+ private System.Windows.Forms.TextBox ActualRATextBox;
+ private System.Windows.Forms.Label ActualPositionLabel;
+ private System.Windows.Forms.Label ActualRALabel;
+ private System.Windows.Forms.Label ActualDecLabel;
+ private System.Windows.Forms.Label TargetDecLabel;
+ private System.Windows.Forms.Label TargetRALabel;
+ private System.Windows.Forms.Label TargetPositionLabel;
+ private System.Windows.Forms.TextBox TargetDecTextBox;
+ private System.Windows.Forms.TextBox TargetRATextBox;
+ private System.Windows.Forms.Timer timer1;
+ private System.Windows.Forms.GroupBox RAIncGroupbox;
+ private System.Windows.Forms.Button tenButton;
+ private System.Windows.Forms.Button fiveButton;
+ private System.Windows.Forms.Button oneButton;
+ private System.Windows.Forms.Button oneForthButton;
+ private System.Windows.Forms.Button editButton;
+ private System.Windows.Forms.Label errorLabel;
+ private System.Windows.Forms.GroupBox overRideGroupbox;
+ private System.Windows.Forms.GroupBox decIncGroupbox;
+ private System.Windows.Forms.Button tenButtonDec;
+ private System.Windows.Forms.Button fiveButtonDec;
+ private System.Windows.Forms.Button oneButtonDec;
+ private System.Windows.Forms.Button oneForthButtonDec;
+ private System.Windows.Forms.GroupBox freeControlGroupbox;
+ private System.Windows.Forms.ComboBox controlScriptsCombo;
+ private System.Windows.Forms.GroupBox groupBox4;
+ private System.Windows.Forms.GroupBox manualGroupBox;
+ private System.Windows.Forms.Label label1;
+ private System.Windows.Forms.Button ccwAzJogButton;
+ private System.Windows.Forms.Button plusElaButton;
+ private System.Windows.Forms.Button subElaButton;
+ private System.Windows.Forms.Button cwAzJogButton;
+ private System.Windows.Forms.TextBox speedTextBox;
+ private System.Windows.Forms.Label label2;
+ private System.Windows.Forms.RadioButton immediateRadioButton;
+ private System.Windows.Forms.RadioButton ControlledButtonRadio;
+ private System.Windows.Forms.Button manualControlButton;
+ private System.Windows.Forms.Label label3;
+ private System.Windows.Forms.Label label4;
+ private System.Windows.Forms.Label label5;
+ private System.Windows.Forms.Button runControlScriptButton;
+ private System.Windows.Forms.Button button1;
+ private System.Windows.Forms.Label label8;
+ private System.Windows.Forms.TextBox statusTextBox;
+ private System.Windows.Forms.TextBox ActualDecTextBox;
+ private System.Windows.Forms.GroupBox spectraCyberGroupBox;
+ private System.Windows.Forms.Button finalizeSettingsButton;
+ private System.Windows.Forms.ComboBox DCGain;
+ private System.Windows.Forms.Button stopScanButton;
+ private System.Windows.Forms.Button startScanButton;
+ private System.Windows.Forms.TextBox frequency;
+ private System.Windows.Forms.Label lblFrequency;
+ private System.Windows.Forms.Label label9;
+ private System.Windows.Forms.TextBox offsetVoltage;
+ private System.Windows.Forms.Label label12;
+ private System.Windows.Forms.ComboBox scanTypeComboBox;
+ private System.Windows.Forms.Label label10;
+ private System.Windows.Forms.TextBox IFGainVal;
+ private System.Windows.Forms.Label lblIFGain;
+ private System.Windows.Forms.ComboBox integrationStepCombo;
+ private System.Windows.Forms.ToolTip IFGainToolTip;
+ private System.Windows.Forms.ToolTip offsetVoltageToolTip;
+ private System.Windows.Forms.ToolTip frequencyToolTip;
+ private System.Windows.Forms.TrackBar speedTrackBar;
+ private System.Windows.Forms.CheckBox SoftwareStopsCheckBox;
+ private System.Windows.Forms.Button stopRT;
+ }
+}
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/GUI/RTControlForm.resx b/ControlRoomApplication/ControlRoomApplication/GUI/RTControlForm.resx
new file mode 100644
index 00000000..eb25514b
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/GUI/RTControlForm.resx
@@ -0,0 +1,132 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ 454, 17
+
+
+ 17, 17
+
+
+ 143, 17
+
+
+ 289, 17
+
+
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/GUI/RTControlFormData.cs b/ControlRoomApplication/ControlRoomApplication/GUI/RTControlFormData.cs
new file mode 100644
index 00000000..22f14f2b
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/GUI/RTControlFormData.cs
@@ -0,0 +1,75 @@
+using System;
+
+namespace ControlRoomApplication.GUI.Data
+{
+ public class RTControlFormData
+ {
+ public int controlScriptIndex { get; set; }
+ public int spectraCyberScanIndex { get; set; }
+ public string frequency { get; set; }
+ public int DCGainIndex { get; set; }
+ public string IFGain { get; set; }
+ public string offsetVoltage { get; set; }
+ public int integrationStepIndex { get; set; }
+ public double speed { get; set; }
+ public bool controlledStopBool { get; set; }
+ public bool immediateStopBool { get; set; }
+ public bool manualControlEnabled { get; set; }
+ public bool freeControlEnabled { get; set; }
+ public bool scanEnabled { get; set; }
+
+
+ public RTControlFormData(int controlScriptIndex, int spectraCyberScanIndex, string frequency, int DCGainIndex, string IFGain, string offsetVoltage,
+ int integrationStepIndex, double speed, bool controlledStopBool, bool immediateStopBool, bool manualControlEnabled, bool freeControlEnabled, bool scanEnabled)
+ {
+ this.controlScriptIndex = controlScriptIndex;
+ this.spectraCyberScanIndex = spectraCyberScanIndex;
+ this.frequency = frequency;
+ this.DCGainIndex = DCGainIndex;
+ this.IFGain = IFGain;
+ this.offsetVoltage = offsetVoltage;
+ this.integrationStepIndex = integrationStepIndex;
+ this.speed = speed;
+ this.immediateStopBool = immediateStopBool;
+ this.controlledStopBool = controlledStopBool;
+ this.manualControlEnabled = manualControlEnabled;
+ this.freeControlEnabled = freeControlEnabled;
+ this.scanEnabled = scanEnabled;
+ }
+
+ public RTControlFormData()
+ {
+ this.controlScriptIndex = 0;
+ this.spectraCyberScanIndex = 0;
+ this.frequency = "" ;
+ this.DCGainIndex = 0;
+ this.IFGain = "";
+ this.offsetVoltage = "";
+ this.integrationStepIndex = 0;
+ this.speed = 0;
+ this.controlledStopBool = true;
+ this.immediateStopBool = false;
+ this.manualControlEnabled = false;
+ this.freeControlEnabled = false;
+ this.scanEnabled = false;
+
+ }
+
+
+
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+}
+
diff --git a/ControlRoomApplication/ControlRoomApplication/Main/Program.cs b/ControlRoomApplication/ControlRoomApplication/Main/Program.cs
index f8cf5e4b..9fd45831 100644
--- a/ControlRoomApplication/ControlRoomApplication/Main/Program.cs
+++ b/ControlRoomApplication/ControlRoomApplication/Main/Program.cs
@@ -1,14 +1,15 @@
using ControlRoomApplication.Controllers;
-using ControlRoomApplication.Controllers.BlkHeadUcontroler;
using ControlRoomApplication.Database;
using ControlRoomApplication.Entities;
using System;
using System.Diagnostics;
+using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
+using log4net;
namespace ControlRoomApplication.Main
@@ -20,308 +21,9 @@ public class Program
[STAThread]
public static void Main(string[] args)
{
- Application.Run(new MainForm());
-
- //DatabaseOperations.DeleteLocalDatabase();
- /*
- SimulatedMicrocontroller micro = new SimulatedMicrocontroller( -20 , 100 );
- micro.BringUp();
- new Thread( new ThreadStart( async () => {// IPAddress.Parse
- while(true) {
- //Console.WriteLine( DateTime.Now ); DateTime.Now.AddSeconds( -1 ) , DateTime.Now
- //Console.WriteLine( DatabaseOperations.GetTEMPData( DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()-(1000*60)*5 , DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() , SensorLocationEnum.AZ_MOTOR ).Count);
- Console.WriteLine( DatabaseOperations.GetCurrentTemp( SensorLocationEnum.EL_MOTOR ).temp+" "+ Constants.TIME.UnixEpoch.AddMilliseconds( DatabaseOperations.GetCurrentTemp( SensorLocationEnum.AZ_MOTOR ).TimeCapturedUTC) );
- Console.WriteLine( DatabaseOperations.GetACCData( DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() - 10000 , DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(), SensorLocationEnum.AZ_MOTOR ).Count );
- Thread.Sleep( 1000 );
- }
- })).Start();
- //*/
-
-
- /*
- //SimulationPLCDriver plc = new SimulationPLCDriver( "127.0.0.1" , "127.0.0.1" , 8080 , 8080 );
- //SimulatedEncoder encoderReader = new SimulatedEncoder( plc, "127.0.0.2" , 1602 );
- EncoderReader encoderReader = new EncoderReader( "192.168.7.2" , 1602 );
-
- System.Timers.Timer timer = new System.Timers.Timer();
- timer.Interval = 1;
- timer.Enabled = true;
-
- Stopwatch sw = Stopwatch.StartNew();
- long start = 0;
-
- Console.WriteLine( encoderReader.GetCurentOrientation().Azimuth );
- Console.WriteLine( encoderReader.GetCurentOrientation().Elevation );
-
- for(int i = 0; i < 1000; i++) {
- encoderReader.GetCurentOrientation();
- }
-
- long end = sw.ElapsedMilliseconds;
-
- Console.WriteLine( "{0} milliseconds passed" , end - start );
-
- /*
- timer.Elapsed += ( o , e ) =>
- {
- start = end;
- end = sw.ElapsedMilliseconds;
- Console.WriteLine( "{0} milliseconds passed" , end - start );
- };
- //*/
-
-
-
-
-
- // MCU_TCPListener.Start(1);
-
- //TcpClient MCUTCPClient = new TcpClient("127.0.0.1", 8080);
- /*
- new Thread(new ThreadStart(() => {
- while (true)
- {
- //Console.WriteLine("---------------------------------");
- ControlRoomApplication.Entities.Orientation one = Controllers.BlkHeadUcontroler.EncoderReader.GetCurentOrientation();
- if (one != null)
- {
- Console.WriteLine(one.Azimuth + " " + one.Elevation);
- }
- Thread.Sleep(100);
- }
- })).Start();
- //ControlRoomApplication.Controllers.BlkHeadUcontroler.MicroControlerControler.BringUp();
-//*/
- /*
- runer();
- async void runer()
- {
- Controllers.ProductionPLCDriver plc = new ControlRoomApplication.Controllers.ProductionPLCDriver(("192.168.0.02"), 502);
- new Thread(plc.HandleClientManagementThread).Start();
-
- Task task = Task.Delay(15000);
- await task;
- int gearedSpeedAZ = 500, gearedSpeedEL = 50;
- ushort homeTimeoutSecondsElevation = 0, homeTimeoutSecondsAzimuth = 0;
-
- Controllers.ProductionMCUDriver MCUDriver = new ControlRoomApplication.Controllers.ProductionMCUDriver("192.168.0.50", 502);
- // MCUDriver.configure_axies(gearedSpeedAZ, gearedSpeedEL, homeTimeoutSecondsAzimuth, homeTimeoutSecondsElevation);
- task = Task.Delay(3000);
- await task;
- // MCUDriver.SendEmptyMoveCommand();
-
- Console.WriteLine(ushort.MaxValue);
- new Thread(new ThreadStart(async () => {// IPAddress.Parse
- Console.WriteLine("---------------------------------");
- Thread.Sleep(1000);
- ushort i = 0, j = 1024;//7500
- plc.configure_muc(gearedSpeedAZ, gearedSpeedEL, homeTimeoutSecondsAzimuth, homeTimeoutSecondsElevation);
- task = Task.Delay(10000);
- await task;
- //Thread.Sleep(10000);
-
- //return;
- while (true)
- {
- Thread.Sleep(5000);
- ushort[] datax = new ushort[20];
- datax[1] = 3;
- datax[11] = 3;
- //Console.WriteLine(datax.Length);
- ushort[] inreg, outreg;
-
- inreg = MCUDriver.MCUModbusMaster.ReadHoldingRegisters(i, (ushort)20);
- outreg = MCUDriver.MCUModbusMaster.ReadHoldingRegisters(j, (ushort)20);
- try
- {
- ushort positionTranslationELInt = 1000, positionTranslationELMSW = 0;
- ushort positionTranslationAZInt = 1000, positionTranslationAZMSW = 0;
- ushort aCCELERATION = 5, programmedPeakSpeedAZInt = 1200;
-
- inreg = MCUDriver.MCUModbusMaster.ReadHoldingRegisters(i, (ushort)20);
- outreg = MCUDriver.MCUModbusMaster.ReadHoldingRegisters(j, (ushort)20);
- //Thread.Sleep(1000);
- ushort[] data = { 0, // Reserved
- 0x0403, // Denotes a relative linear interpolated move and a Trapezoidal S-Curve profile
- (ushort)(programmedPeakSpeedAZInt >> 0x10), // MSW for azimuth speed
- (ushort)(programmedPeakSpeedAZInt & 0xFFFF), // LSW for azimuth speed
- aCCELERATION, // Acceleration for azimuth
- aCCELERATION, // Deceleration for azimuth
- positionTranslationAZMSW, // MSW for azimuth position 6
- (ushort)(positionTranslationAZInt & 0xFFFF), // LSW for azimuth position 7
- 0, // Reserved
- 0, // Reserved
- 0, // Reserved
- 0, // Reserved
- positionTranslationELMSW, // MSW for elevation position 12
- (ushort)(positionTranslationELInt & 0xFFFF), // LSW for elevation position 13
- 0, // Reserved
- 0, // Reserved
- 0, // Reserved
- 0, // Reserved
- 0, // Reserved
- 0 // Reserved
- };
-
- await plc.sendmovecomand(programmedPeakSpeedAZInt, aCCELERATION, positionTranslationAZInt, positionTranslationELInt);
-
- // MCUDriver.MCUModbusMaster.WriteMultipleRegisters(j, data);
- // Thread.Sleep(10);
- // MCUDriver.MCUModbusMaster.WriteMultipleRegisters(j, datax);
-
- // data[1] = 0x403;
- // APLCDriver.PLCModbusMaster.WriteMultipleRegisters(j, data);
- // i = 25;
- //MCUDriver.configureSingleaxys(gearedSpeedAZ, (ushort)gearedSpeedEL,0);
- //MCUDriver.configureaxies(gearedSpeedAZ, gearedSpeedEL, homeTimeoutSecondsAzimuth, homeTimeoutSecondsElevation);
- //MCUDriver.configureSingleaxys(gearedSpeedAZ, homeTimeoutSecondsAzimuth, 0);
- //System.Threading.Thread.Sleep(50);
- //MCUDriver.configureSingleaxys(gearedSpeedEL, homeTimeoutSecondsElevation, 1);
- inreg = MCUDriver.MCUModbusMaster.ReadHoldingRegisters(i, (ushort)20);
- outreg = MCUDriver.MCUModbusMaster.ReadHoldingRegisters(j, (ushort)20);
- }
- catch (Exception e)
- {
- Console.WriteLine(e);
- Console.WriteLine("read reg {0,6} failed", i);
- continue;
- }
- if (inreg == null) { return; }
- string outstr = " inreg";
- for (int v = 0; v < inreg.Length; v++)
- {
- //outstr += Convert.ToString(inreg[v], 2).PadLeft(16).Replace(" ", "0") + " , ";
- outstr += Convert.ToString(inreg[v], 10).PadLeft(8) + ",";
- }
- outstr += "\noutreg";
- for (int v = 0; v < outreg.Length; v++)
- {
- //outstr += Convert.ToString(outreg[v], 2).PadLeft(16).Replace(" ", "0") + " , ";
- outstr += Convert.ToString(outreg[v], 10).PadLeft(8) + ",";
- }
- Console.WriteLine(outstr);
- //Console.WriteLine("read reg {0,6} suceded {1} *****************************************************", i, outstr);
- //break;
- //Thread.Sleep(10);
- }
- })).Start();
- }
-
-
- //*/
- /*
- Controllers.ProductionPLCDriver APLCDriver;
- new Thread(new ThreadStart(() => {
- Console.WriteLine("---------------------------------");
- APLCDriver = new ControlRoomApplication.Controllers.ProductionPLCDriver("192.168.0.2", 502);
- Thread.Sleep(Timeout.Infinite);
- })).Start();
- ///
-
- new Thread(new ThreadStart(() => {
- bool up = true;
- ushort i = 0;
- Random rand = new Random();
- Thread.Sleep(10000);
- while (true)
- {
- Thread.Sleep(1000);
- string outp = "";
- for (ushort v = 0; v < 10; v++)
- {
- outp += Convert.ToString(APLCDriver.readregval(v), 2).PadLeft(16).Replace(" ", "0") + " , ";
- }
- Console.WriteLine(outp);
- if (up) { i++; } else { i--; }
- if (i>=10){ up = false; }
- if (i <=0){ up = true; }
- APLCDriver.setregvalue(i, (ushort) (rand.Next() /(2^16) ));
-
- }
- })).Start();
- //*/
-
- //string localhostIP = PLCConstants.LOCAL_HOST_IP;
- //int localhostPort = PLCConstants.PORT_8080;
- //string mcuIP = MCUConstants.ACTUAL_MCU_IP_ADDRESS;
- //int mcuPort = MCUConstants.ACTUAL_MCU_MODBUS_TCP_PORT;
-
- //RadioTelescopeController RTController = new RadioTelescopeController(
- // new RadioTelescope(
- // new SpectraCyberSimulatorController(new SpectraCyberSimulator()),
- // new PLCClientCommunicationHandler(localhostIP, localhostPort),
- // MiscellaneousConstants.JOHN_RUDY_PARK,
- // new Orientation(0, 90)
- // )
- //);
-
- //ProductionPLCDriver PLCDriver = new ProductionPLCDriver(localhostIP, localhostPort);
-
- //if (!PLCDriver.StartAsyncAcceptingClients())
- //{
- // Console.WriteLine("[Program] ERROR starting to async accept clients.");
- // return;
- //}
-
- //RTController.RadioTelescope.PLCClient.ConnectToServer();
- //Thread.Sleep(100);
-
- //PLCDriver.FetchMCUModbusSlave(mcuIP, mcuPort);
- //Thread.Sleep(100);
-
- //if (RTController.TestCommunication())
- //{
- // Console.WriteLine("[Program] Successfully communicated with MCU over Modbus TCP/IP!");
- //}
- //else
- //{
- // Console.WriteLine("[Program] ERROR communicating with MCU over Modbus TCP/IP.");
- // return;
- //}
-
- //Thread.Sleep(100);
-
- //if (RTController.ConfigureRadioTelescope(100, 100, 210, 210))
- //{
- // Console.WriteLine("[Program] Successfully configured MCU over Modbus TCP/IP!");
- //}
- //else
- //{
- // Console.WriteLine("[Program] ERROR configuring MCU over Modbus TCP/IP.");
- // return;
- //}
-
- //Thread.Sleep(3000);
-
- //if (RTController.StartRadioTelescopeAzimuthJog(166667, false))
- //{
- // Console.WriteLine("[Program] Successfully sent jog move request to MCU over Modbus TCP/IP!");
- //}
- //else
- //{
- // Console.WriteLine("[Program] ERROR sending jog move request to MCU over Modbus TCP/IP.");
- // return;
- //}
-
- //for (int i = 0; i < 5; i++)
- //{
- // Thread.Sleep(2000);
- // Console.WriteLine("Current at i=" + i.ToString() + ": " + RTController.GetCurrentOrientation().Azimuth.ToString());
- //}
-
- //if (PLCDriver.SendHoldMoveCommand())
- //{
- // Console.WriteLine("[Program] Successfully sent hold move request to MCU over Modbus TCP/IP!");
- //}
- //else
- //{
- // Console.WriteLine("[Program] ERROR sending hold move request to MCU over Modbus TCP/IP.");
- // return;
- //}
-
- //Console.WriteLine("[Program] Done.");
-
- //Thread.Sleep(10000);
+ MainForm mainForm = new MainForm();
+ ((log4net.Repository.Hierarchy.Hierarchy)log4net.LogManager.GetLoggerRepository()).Root.AddAppender(mainForm);
+ Application.Run(mainForm);
}
}
}
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/Migrations/201904150402332_LoggingUpdgrades.cs b/ControlRoomApplication/ControlRoomApplication/Migrations/201904150402332_LoggingUpdgrades.cs
index 734b0539..558b5030 100644
--- a/ControlRoomApplication/ControlRoomApplication/Migrations/201904150402332_LoggingUpdgrades.cs
+++ b/ControlRoomApplication/ControlRoomApplication/Migrations/201904150402332_LoggingUpdgrades.cs
@@ -10,25 +10,28 @@ public override void Up()
CreateTable(
"dbo.appointment",
c => new
- {
- Id = c.Int(nullable: false, identity: true),
- user_id = c.Int(nullable: false),
- start_time = c.DateTime(nullable: false, precision: 0),
- end_time = c.DateTime(nullable: false, precision: 0),
- telescope_id = c.Int(nullable: false),
- status = c.Int(nullable: false),
- type = c.Int(nullable: false),
- CelestialBody_Id = c.Int(),
- Orientation_Id = c.Int(),
- SpectraCyberConfig_Id = c.Int(nullable: false),
- })
+ {
+ Id = c.Int(nullable: false, identity: true),
+ user_id = c.Int(nullable: false),
+ start_time = c.DateTime(nullable: false, precision: 0),
+ end_time = c.DateTime(nullable: false, precision: 0),
+ telescope_id = c.Int(nullable: false),
+ status = c.Int(nullable: false),
+ type = c.Int(nullable: false),
+ Celestial_Body_Id = c.Int(),
+
+ // commented out spectra cyber due to backend team not being able to develop feature this semester
+
+ Orientation_Id = c.Int(),
+ // SpectraCyberConfig_Id = c.Int(nullable: false),
+ })
.PrimaryKey(t => t.Id)
- .ForeignKey("dbo.celestial_body", t => t.CelestialBody_Id)
+ .ForeignKey("dbo.celestial_body", t => t.Celestial_Body_Id)
.ForeignKey("dbo.orientation", t => t.Orientation_Id)
- .ForeignKey("dbo.spectracyber_config", t => t.SpectraCyberConfig_Id, cascadeDelete: true)
- .Index(t => t.CelestialBody_Id)
- .Index(t => t.Orientation_Id)
- .Index(t => t.SpectraCyberConfig_Id);
+ // .ForeignKey("dbo.spectracyber_config", t => t.SpectraCyberConfig_Id, cascadeDelete: true)
+ .Index(t => t.Celestial_Body_Id)
+ .Index(t => t.Orientation_Id);
+ // .Index(t => t.SpectraCyberConfig_Id);
CreateTable(
"dbo.celestial_body",
@@ -109,18 +112,21 @@ public override void Up()
public override void Down()
{
- DropForeignKey("dbo.appointment", "SpectraCyberConfig_Id", "dbo.spectracyber_config");
+
+ // commented out spectra cyber due to backend team not being able to develop feature this semester
+
+ // DropForeignKey("dbo.appointment", "SpectraCyberConfig_Id", "dbo.spectracyber_config");
DropForeignKey("dbo.rf_data", "appointment_id", "dbo.appointment");
DropForeignKey("dbo.appointment", "Orientation_Id", "dbo.orientation");
DropForeignKey("dbo.coordinate", "Appointment_Id", "dbo.appointment");
- DropForeignKey("dbo.appointment", "CelestialBody_Id", "dbo.celestial_body");
+ DropForeignKey("dbo.appointment", "Celestial_Body_Id", "dbo.celestial_body");
DropForeignKey("dbo.celestial_body", "Coordinate_Id", "dbo.coordinate");
DropIndex("dbo.rf_data", new[] { "appointment_id" });
DropIndex("dbo.coordinate", new[] { "Appointment_Id" });
DropIndex("dbo.celestial_body", new[] { "Coordinate_Id" });
DropIndex("dbo.appointment", new[] { "SpectraCyberConfig_Id" });
DropIndex("dbo.appointment", new[] { "Orientation_Id" });
- DropIndex("dbo.appointment", new[] { "CelestialBody_Id" });
+ DropIndex("dbo.appointment", new[] { "Celestial_Body_Id" });
DropTable("dbo.telescope_log");
DropTable("dbo.spectracyber_config");
DropTable("dbo.rf_data");
diff --git a/ControlRoomApplication/ControlRoomApplication/Properties/Resources.Designer.cs b/ControlRoomApplication/ControlRoomApplication/Properties/Resources.Designer.cs
new file mode 100644
index 00000000..534d071f
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Properties/Resources.Designer.cs
@@ -0,0 +1,63 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace ControlRoomApplication.Properties {
+ using System;
+
+
+ ///
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ ///
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // 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", "15.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ 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() {
+ }
+
+ ///
+ /// 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)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ControlRoomApplication.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 {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplication/Properties/Resources.resx b/ControlRoomApplication/ControlRoomApplication/Properties/Resources.resx
new file mode 100644
index 00000000..1af7de15
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Properties/Resources.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/Simulators/Hardware/PLC_MCU/Simulation_control_pannel.cs b/ControlRoomApplication/ControlRoomApplication/Simulators/Hardware/PLC_MCU/Simulation_control_pannel.cs
index b6348173..927de96f 100644
--- a/ControlRoomApplication/ControlRoomApplication/Simulators/Hardware/PLC_MCU/Simulation_control_pannel.cs
+++ b/ControlRoomApplication/ControlRoomApplication/Simulators/Hardware/PLC_MCU/Simulation_control_pannel.cs
@@ -1,4 +1,6 @@
-using ControlRoomApplication.Entities;
+using ControlRoomApplication.Constants;
+using ControlRoomApplication.Controllers;
+using ControlRoomApplication.Entities;
using Modbus.Data;
using Modbus.Device;
using System;
@@ -6,16 +8,18 @@
using System.Net;
using System.Net.Sockets;
using System.Threading;
+using ControlRoomApplication.Util;
+using ControlRoomApplication.Controllers.PLCCommunication.PLCDrivers.MCUManager;
+
+namespace ControlRoomApplication.Simulators.Hardware.PLC_MCU {
+ class Simulation_control_pannel {
+ private static readonly log4net.ILog logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
-namespace ControlRoomApplication.Simulators.Hardware.PLC_MCU
-{
- class Simulation_control_pannel
- {
private TcpListener MCU_TCPListener;
private ModbusSlave MCU_Modbusserver;
private TcpClient PLCTCPClient;
- private ModbusIpMaster PLCModbusMaster;
+ public ModbusIpMaster PLCModbusMaster;
private Thread MCU_emulator_thread;
private Thread PLC_emulator_thread;
@@ -23,133 +27,184 @@ class Simulation_control_pannel
private string PLC_ip;
private int PLC_port;
- private bool runsimulator = true, mooving = false,jogging=false;
+ private bool runsimulator = true, mooving = false, jogging = false, isconfigured = false, isTest = false;
- private int acc, distAZ, distEL, currentAZ, currentEL, AZ_speed, EL_speed;
+ private int acc, distAZ, distEL, currentAZ, currentEL, AZ_speed, EL_speed;
+
+ private int EL0Lim_ON = -ConversionHelper.DegreesToSteps(15, MotorConstants.GEARING_RATIO_ELEVATION );
+ private int EL90Lim_ON = ConversionHelper.DegreesToSteps(93, MotorConstants.GEARING_RATIO_ELEVATION );
+
+ private int EL0Lim_OFF = -ConversionHelper.DegreesToSteps(4, MotorConstants.GEARING_RATIO_ELEVATION );
+ private int EL90Lim_OFF = ConversionHelper.DegreesToSteps(89, MotorConstants.GEARING_RATIO_ELEVATION );
+
+ bool AZ10LimStatus = false, AZ370LimStatus = false, EL0LimStatus = false, EL90LimStatus = false;
+
+ public Simulation_control_pannel( string PLC_ip , string MCU_ip , int MCU_port , int PLC_port , bool istest ) {
- public Simulation_control_pannel(string PLC_ip, string MCU_ip, int MCU_port, int PLC_port)
- {
- // PLCTCPClient = new TcpClient(PLC_ip, PLC_port);
- // PLCModbusMaster = ModbusIpMaster.CreateIp(PLCTCPClient);
this.PLC_ip = PLC_ip;
this.PLC_port = PLC_port;
+ isTest = istest;
+ try {
- try
- {
- PLC_emulator_thread = new Thread(new ThreadStart(Run_PLC_emulator_thread));
- //MCU_TCPListener = new TcpListener(new IPEndPoint(IPAddress.Parse("127.0.0.2"), 8080));
- //Console.WriteLine(MCU_ip,)
- MCU_TCPListener = new TcpListener(new IPEndPoint(IPAddress.Parse(MCU_ip), MCU_port));
- MCU_emulator_thread = new Thread(new ThreadStart(Run_MCU_server_thread));
- }
- catch (Exception e){
- if ((e is ArgumentNullException) || (e is ArgumentOutOfRangeException)){
- Console.WriteLine(e);
+ MCU_TCPListener = new TcpListener( new IPEndPoint( IPAddress.Parse( MCU_ip ) , MCU_port ) );
+ MCU_emulator_thread = new Thread( new ThreadStart( Run_MCU_server_thread ) ) { Name="MCU Simulator Thread"};
+ } catch(Exception e) {
+ if((e is ArgumentNullException) || (e is ArgumentOutOfRangeException)) {
+ logger.Error(e);
return;
- }
- else { throw e; }// Unexpected exception
+ } else { throw e; }// Unexpected exception
}
- try{
- MCU_TCPListener.Start(1);
- }catch (Exception e){
- if ((e is SocketException) || (e is ArgumentOutOfRangeException) || (e is InvalidOperationException)){
- Console.WriteLine(e);
+ try {
+ MCU_TCPListener.Start( 1 );
+ } catch(Exception e) {
+ if((e is SocketException) || (e is ArgumentOutOfRangeException) || (e is InvalidOperationException)) {
+ logger.Error(e);
return;
}
}
runsimulator = true;
- PLC_emulator_thread.Start();
MCU_emulator_thread.Start();
}
+ public void startPLC() {
+ try {
+ PLC_emulator_thread = new Thread( new ThreadStart( Run_PLC_emulator_thread ) ) { Name = "PLC simulator thread"};
+ PLC_emulator_thread.Start();
+ } catch(Exception e) {
+ if((e is ArgumentNullException) || (e is ArgumentOutOfRangeException)) {
+ logger.Error(e);
+ return;
+ }
+
+ }
+ }
public void Bring_down()
{
runsimulator = false;
- PLC_emulator_thread.Join(100);
- MCU_emulator_thread.Join();
+ if(MCU_Modbusserver != null) MCU_Modbusserver.Dispose();
+ PLC_emulator_thread.Join();
+ PLCTCPClient.Dispose();
+ PLCModbusMaster.Dispose();
+ if(MCU_emulator_thread.IsAlive) MCU_emulator_thread.Join();
+ MCU_TCPListener.Stop();
}
- private void Run_PLC_emulator_thread(){
- while (runsimulator){
- try{
- PLCTCPClient = new TcpClient(this.PLC_ip, this.PLC_port);
- PLCModbusMaster = ModbusIpMaster.CreateIp(PLCTCPClient);
+ private void Run_PLC_emulator_thread() {
+ while(runsimulator) {
+ try {
+ PLCTCPClient = new TcpClient( this.PLC_ip , this.PLC_port );
+ PLCModbusMaster = ModbusIpMaster.CreateIp( PLCTCPClient );
+ } catch {//no server setup on control room yet
+ logger.Info(Utilities.GetTimeStamp() + ": ________________PLC sim awaiting control room");
}
- catch {//no server setup on control room yet
- Console.WriteLine("________________PLC sim awaiting control room");
- Thread.Sleep(1000);
- }
- Console.WriteLine("________________PLC sim running");
- PLCModbusMaster.WriteMultipleRegisters( (ushort)PLC_modbus_server_register_mapping.Safty_INTERLOCK-1 ,new ushort[] {1} );
- while (runsimulator){
- Thread.Sleep(50);
+ logger.Info(Utilities.GetTimeStamp() + ": ________________PLC sim running");
+ PLCModbusMaster.WriteMultipleRegisters( (ushort)PLC_modbus_server_register_mapping.Gate_Safety_INTERLOCK , new ushort[] { BoolToInt( true ) } );
+ while(runsimulator) {
+ if(isTest) {
+ PLCModbusMaster.WriteMultipleRegisters( (ushort)PLC_modbus_server_register_mapping.Gate_Safety_INTERLOCK , new ushort[] { BoolToInt( true ) } );
+ Thread.Sleep( 5 );
+ continue;
+ } else {
+ if(!EL0LimStatus) {
+ if(currentEL < EL0Lim_ON) {
+ EL0LimStatus = (currentEL < EL0Lim_ON);
+ PLCModbusMaster.WriteMultipleRegisters( (ushort)PLC_modbus_server_register_mapping.EL_10_LIMIT , new ushort[] { BoolToInt( !EL0LimStatus ) } );
+ }
+ } else if(currentEL > EL0Lim_OFF) {
+ EL0LimStatus = (currentEL > EL0Lim_OFF);
+ PLCModbusMaster.WriteMultipleRegisters( (ushort)PLC_modbus_server_register_mapping.EL_10_LIMIT , new ushort[] { BoolToInt( !EL0LimStatus ) } );
+ }
+
+ if(!EL90LimStatus) {
+ if(currentEL > EL90Lim_ON) {
+ EL90LimStatus = (currentEL > EL90Lim_ON);
+ PLCModbusMaster.WriteMultipleRegisters( (ushort)PLC_modbus_server_register_mapping.EL_90_LIMIT , new ushort[] { BoolToInt( !EL90LimStatus ) } );
+ }
+ } else if(currentEL < EL90Lim_OFF) {
+ EL90LimStatus = (currentEL < EL90Lim_OFF);
+ PLCModbusMaster.WriteMultipleRegisters( (ushort)PLC_modbus_server_register_mapping.EL_90_LIMIT , new ushort[] { BoolToInt( !EL90LimStatus ) } );
+ }
+ }
+ Thread.Sleep( 50 );
}
}
}
+ private void Server_Written_to_handler( object sender , DataStoreEventArgs e ) {
+ MCU_Modbusserver.DataStore.HoldingRegisters[1] = (ushort)(MCU_Modbusserver.DataStore.HoldingRegisters[1] & 0xff7f);
+ MCU_Modbusserver.DataStore.HoldingRegisters[11] = (ushort)(MCU_Modbusserver.DataStore.HoldingRegisters[11] & 0xff7f);
+ ushort[] data = new ushort[20];//e.Data.B.Count
+ if (e.StartAddress >= 1023)
+ {
+ data = Copy_modbus_registers(1025, 20);
+ handleTestCMD(data);
+ }
+ }
- private void Run_MCU_server_thread(){
+ private void Run_MCU_server_thread() {
byte slaveId = 1;
// create and start the TCP slave
- MCU_Modbusserver = ModbusTcpSlave.CreateTcp(slaveId, MCU_TCPListener);
+ MCU_Modbusserver = ModbusTcpSlave.CreateTcp( slaveId , MCU_TCPListener );
//coils, inputs, holdingRegisters, inputRegisters
- MCU_Modbusserver.DataStore = DataStoreFactory.CreateDefaultDataStore(0, 0, 1054, 0);
+ MCU_Modbusserver.DataStore = DataStoreFactory.CreateDefaultDataStore( 0 , 0 , 1054 , 0 );
// PLC_Modbusserver.DataStore.SyncRoot.ToString();
//MCU_Modbusserver.ModbusSlaveRequestReceived += new EventHandler(Server_Read_handler);
- //MCU_Modbusserver.DataStore.DataStoreWrittenTo += new EventHandler(Server_Written_to_handler);
+ if(isTest) {
+ MCU_Modbusserver.DataStore.DataStoreWrittenTo += new EventHandler( Server_Written_to_handler );
+ }
MCU_Modbusserver.Listen();
// prevent the main thread from exiting
- ushort[] previos_out,current_out;
- previos_out = Copy_modbus_registers(1025, 20);
- while (runsimulator){
- current_out = Copy_modbus_registers(1025, 20);
- if(!current_out.SequenceEqual(previos_out)){
- handleCMD(current_out);
+ ushort[] previos_out, current_out;
+ previos_out = Copy_modbus_registers( 1025 , 20 );
+ while(runsimulator) {
+ Thread.Sleep( 1 );
+ if(isTest) {
+ continue;
+ }
+ current_out = Copy_modbus_registers( 1025 , 20 );
+ if(!current_out.SequenceEqual( previos_out )) {
+ handleCMD( current_out );
//Console.WriteLine("data changed");
}
- if (mooving){
- if (distAZ != 0 || distEL != 0)
- {
+ if(mooving) {
+ if(distAZ != 0 || distEL != 0) {
int travAZ = (distAZ < -AZ_speed) ? -AZ_speed : (distAZ > AZ_speed) ? AZ_speed : distAZ;
int travEL = (distEL < -EL_speed) ? -EL_speed : (distEL > EL_speed) ? EL_speed : distEL;
move( travAZ , travEL );
- }
- else
- {
+ } else {
mooving = false;
MCU_Modbusserver.DataStore.HoldingRegisters[1] = (ushort)(MCU_Modbusserver.DataStore.HoldingRegisters[1] | 0x0080);
+ MCU_Modbusserver.DataStore.HoldingRegisters[11] = (ushort)(MCU_Modbusserver.DataStore.HoldingRegisters[11] | 0x0080);
}
}
if(jogging) {
move( AZ_speed , EL_speed );
}
previos_out = current_out;
- Thread.Sleep(50);
}
-
+
}
- private bool move(int travAZ , int travEL ){
+ private bool move( int travAZ , int travEL ) {
distAZ -= travAZ;
distEL -= travEL;
currentAZ += travAZ;
currentEL += travEL;
- // Console.WriteLine("offset: az" + currentAZ + " el " + currentEL);
- MCU_Modbusserver.DataStore.HoldingRegisters[3]= (ushort)(currentAZ>>16);
- MCU_Modbusserver.DataStore.HoldingRegisters[4] = (ushort)(currentAZ);
- MCU_Modbusserver.DataStore.HoldingRegisters[13] = (ushort)(currentEL >> 16);
- MCU_Modbusserver.DataStore.HoldingRegisters[14] = (ushort)(currentEL);
- //string outstr = "outreg";
- // for (int v = 0; v < 20; v++)
- // {
- // outstr += Convert.ToString(MCU_Modbusserver.DataStore.HoldingRegisters[v], 16).PadLeft(5) + ",";
- // }
- // Console.WriteLine(outstr);
+
+ MCU_Modbusserver.DataStore.HoldingRegisters[3] = (ushort)((currentAZ & 0xffff0000) >> 16);
+ MCU_Modbusserver.DataStore.HoldingRegisters[4] = (ushort)(currentAZ & 0xffff);
+ MCU_Modbusserver.DataStore.HoldingRegisters[13] = (ushort)((currentEL & 0xffff0000) >> 16);
+ MCU_Modbusserver.DataStore.HoldingRegisters[14] = (ushort)(currentEL & 0xffff);
+
+ MCU_Modbusserver.DataStore.HoldingRegisters[5] = (ushort)(((int)(currentAZ/2.5) & 0xffff0000) >> 16);
+ MCU_Modbusserver.DataStore.HoldingRegisters[6] = (ushort)((int)(currentAZ / 2.5) & 0xffff);
+ MCU_Modbusserver.DataStore.HoldingRegisters[15] = (ushort)(((int)(currentEL / 2.5) & 0xffff0000) >> 16);
+ MCU_Modbusserver.DataStore.HoldingRegisters[16] = (ushort)((int)(currentEL / 2.5) & 0xffff);
return true;
}
@@ -159,62 +214,148 @@ private bool handleCMD( ushort[] data ) {
for(int v = 0; v < data.Length; v++) {
outstr += Convert.ToString( data[v] , 16 ).PadLeft( 5 ) + ",";
}
- Console.WriteLine( outstr );
+ Console.WriteLine(outstr);
jogging = false;
- if(data[1] == 0x0403) {//move cmd
+ if((data[0] & 0xf000) == 0x8000) {//if not configured dont move
+
+ isconfigured = true;
+ } else if(!isconfigured) {
+ return true;
+ }
+
+ if (data[1] == 0x0403) {//move cmd
mooving = true;
MCU_Modbusserver.DataStore.HoldingRegisters[1] = (ushort)(MCU_Modbusserver.DataStore.HoldingRegisters[1] & 0xff7f);
+ MCU_Modbusserver.DataStore.HoldingRegisters[11] = (ushort)(MCU_Modbusserver.DataStore.HoldingRegisters[11] & 0xff7f);
AZ_speed = (data[2] << 16) + data[3];
- AZ_speed /= 5;
+ AZ_speed /= 250;
EL_speed = AZ_speed;
acc = data[4];
distAZ = (data[6] << 16) + data[7];
distEL = (data[12] << 16) + data[13];
+ Console.WriteLine("moving to at ({0} , {1}) at ({2} , {3}) steps per second", distAZ, distEL, AZ_speed, EL_speed);
return true;
- } else if(data[0] == 0x0080 || data[0] == 0x0100 || data[10] == 0x0080 || data[10] == 0x0100) {
+ } else if (data[0] == 0x0080 || data[0] == 0x0100 || data[10] == 0x0080 || data[10] == 0x0100) {
jogging = true;
MCU_Modbusserver.DataStore.HoldingRegisters[1] = (ushort)(MCU_Modbusserver.DataStore.HoldingRegisters[1] & 0xff7f);
- if(data[0] == 0x0080) {
- AZ_speed = ((data[4] << 16) + data[5]) / 20;
- }
- else if(data[0] == 0x0100) {
- AZ_speed = -((data[4] << 16) + data[5]) / 20;
+ MCU_Modbusserver.DataStore.HoldingRegisters[11] = (ushort)(MCU_Modbusserver.DataStore.HoldingRegisters[11] & 0xff7f);
+ if (data[0] == 0x0080) {
+ AZ_speed = ((data[4] << 16) + data[5]) / 1000;
+ } else if (data[0] == 0x0100) {
+ AZ_speed = -((data[4] << 16) + data[5]) / 1000;
} else {
AZ_speed = 0;
}
- if(data[10] == 0x0080) {
- EL_speed = ((data[14] << 16) + data[15]) / 20;
- }
- else if(data[10] == 0x0100) {
- EL_speed = -((data[14] << 16) + data[15]) / 20;
+ if (data[10] == 0x0080) {
+ EL_speed = ((data[14] << 16) + data[15]) / 1000;
+ } else if (data[10] == 0x0100) {
+ EL_speed = -((data[14] << 16) + data[15]) / 1000;
} else {
EL_speed = 0;
}
+ Console.WriteLine("jogging at {0} {1}", AZ_speed, EL_speed);
return true;
- } else if(data[0] == 0x0002 || data[0] == 0x0002) {//move cmd
+ } else if (data[0] == 0x0002 || data[10] == 0x0002) {//move cmd
mooving = true;
MCU_Modbusserver.DataStore.HoldingRegisters[1] = (ushort)(MCU_Modbusserver.DataStore.HoldingRegisters[1] & 0xff7f);
- AZ_speed = ((data[4] << 16) + data[5]) / 5;
- EL_speed = ((data[14] << 16) + data[15]) / 5;
+ MCU_Modbusserver.DataStore.HoldingRegisters[11] = (ushort)(MCU_Modbusserver.DataStore.HoldingRegisters[11] & 0xff7f);
+ AZ_speed = ((data[4] << 16) + data[5]) / 250;
+ EL_speed = ((data[14] << 16) + data[15]) / 250;
acc = data[6];
distAZ = (data[2] << 16) + data[3];
distEL = (data[12] << 16) + data[13];
+ Console.WriteLine("also moving to at ({0} , {1}) at ({2} , {3}) steps per second", distAZ, distEL, AZ_speed, EL_speed);
return true;
}
+
+ // Homing
+ else if ((data[(int)MCURegPos.firstWordAzimuth] == (ushort)RadioTelescopeDirectionEnum.ClockwiseHoming ||
+ data[(int)MCURegPos.firstWordAzimuth] == (ushort)RadioTelescopeDirectionEnum.CounterclockwiseHoming) &&
+ (data[(int)MCURegPos.firstWordElevation] == (ushort)RadioTelescopeDirectionEnum.ClockwiseHoming ||
+ data[(int)MCURegPos.firstWordElevation] == (ushort)RadioTelescopeDirectionEnum.CounterclockwiseHoming))
+ {
+ // If we're homing, set the position to 0 and say we are At_Home
+ currentAZ = 0;
+ currentEL = 0;
+
+ // Update position registers
+ move(0, 0);
+
+ // Update At_Home bit
+ MCU_Modbusserver.DataStore.HoldingRegisters[(int)MCUConstants.MCUOutputRegs.AZ_Status_Bist_MSW + 1] |= 1 << (int)MCUConstants.MCUStatusBitsMSW.At_Home;
+ }
+ else {
+ //logger.Info("SIMULATION CONTROL PANEL: Invalid telescope movement command");
+ }
return false;
}
- private ushort[] Copy_modbus_registers(int start_index,int length)
- {
- ushort[] data = new ushort[length];
- for(int i = 0; i < length; i++)
+ private bool handleTestCMD( ushort[] data ) {
+ string outstr = " inreg";
+ for(int v = 0; v < data.Length; v++) {
+ outstr += Convert.ToString( data[v] , 16 ).PadLeft( 5 ) + ",";
+ }
+ Console.WriteLine(outstr);
+ if (data[1] == 0x0403)//move cmd
+ {
+ distAZ = (data[6] << 16) + data[7];
+ distEL = (data[12] << 16) + data[13];
+ Console.WriteLine( "AZ_22 {0,16} EL_22 {1,16}" , (MCU_Modbusserver.DataStore.HoldingRegisters[3] << 16) + MCU_Modbusserver.DataStore.HoldingRegisters[4] , (MCU_Modbusserver.DataStore.HoldingRegisters[13] << 16) + MCU_Modbusserver.DataStore.HoldingRegisters[14] );
+
+ move( distAZ , distEL );
+ MCU_Modbusserver.DataStore.HoldingRegisters[1] = (ushort)(MCU_Modbusserver.DataStore.HoldingRegisters[1] | 0x0080);
+ MCU_Modbusserver.DataStore.HoldingRegisters[11] = (ushort)(MCU_Modbusserver.DataStore.HoldingRegisters[11] | 0x0080);
+
+ Console.WriteLine( "AZ_finni1 {0,10} EL_finni1 {1,10}" , (MCU_Modbusserver.DataStore.HoldingRegisters[3] << 16) + MCU_Modbusserver.DataStore.HoldingRegisters[4] , (MCU_Modbusserver.DataStore.HoldingRegisters[13] << 16) + MCU_Modbusserver.DataStore.HoldingRegisters[14] );
+
+ return true;
+ } else if(data[0] == 0x0002 || data[0] == 0x0002) {//move cmd
+ MCU_Modbusserver.DataStore.HoldingRegisters[1] = (ushort)(MCU_Modbusserver.DataStore.HoldingRegisters[1] & 0xff7f);
+ MCU_Modbusserver.DataStore.HoldingRegisters[11] = (ushort)(MCU_Modbusserver.DataStore.HoldingRegisters[11] & 0xff7f);
+ distAZ = (data[2] << 16) + data[3];
+ distEL = (data[12] << 16) + data[13];
+
+ move( distAZ , distEL );
+ MCU_Modbusserver.DataStore.HoldingRegisters[1] = (ushort)(MCU_Modbusserver.DataStore.HoldingRegisters[1] | 0x0080);
+ MCU_Modbusserver.DataStore.HoldingRegisters[11] = (ushort)(MCU_Modbusserver.DataStore.HoldingRegisters[11] | 0x0080);
+
+ return true;
+ }
+
+ // Homing
+ else if ((data[(int)MCURegPos.firstWordAzimuth] == (ushort)RadioTelescopeDirectionEnum.ClockwiseHoming ||
+ data[(int)MCURegPos.firstWordAzimuth] == (ushort)RadioTelescopeDirectionEnum.CounterclockwiseHoming) &&
+ (data[(int)MCURegPos.firstWordElevation] == (ushort)RadioTelescopeDirectionEnum.ClockwiseHoming ||
+ data[(int)MCURegPos.firstWordElevation] == (ushort)RadioTelescopeDirectionEnum.CounterclockwiseHoming))
{
- data[i] = MCU_Modbusserver.DataStore.HoldingRegisters[i+start_index];
+ // If we're homing, set the position to 0 and say we are At_Home
+ currentAZ = 0;
+ currentEL = 0;
+
+ // Update position registers
+ move(0, 0);
+
+ // Update At_Home bit
+ MCU_Modbusserver.DataStore.HoldingRegisters[(int)MCUConstants.MCUOutputRegs.AZ_Status_Bist_MSW + 1] |= 1 << (int)MCUConstants.MCUStatusBitsMSW.At_Home;
}
- return data;
+ return false;
}
+ private ushort[] Copy_modbus_registers( int start_index , int length ) {
+ ushort[] data = new ushort[length];
+ for(int i = 0; i < length; i++) {
+ data[i] = MCU_Modbusserver.DataStore.HoldingRegisters[i + start_index];
+ }
+ return data;
+ }
+
+ private ushort BoolToInt(bool i ) {
+ if(!i) {
+ return 0;
+ } else return 1;
+ }
}
}
+
diff --git a/ControlRoomApplication/ControlRoomApplication/Simulators/Hardware/PLC_MCU/Test_control_pannel.cs b/ControlRoomApplication/ControlRoomApplication/Simulators/Hardware/PLC_MCU/Test_control_pannel.cs
deleted file mode 100644
index 928a75d3..00000000
--- a/ControlRoomApplication/ControlRoomApplication/Simulators/Hardware/PLC_MCU/Test_control_pannel.cs
+++ /dev/null
@@ -1,205 +0,0 @@
-using ControlRoomApplication.Entities;
-using Modbus.Data;
-using Modbus.Device;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Net;
-using System.Net.Sockets;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace ControlRoomApplication.Simulators.Hardware.PLC_MCU
-{
- class Test_control_pannel
- {
- private TcpListener MCU_TCPListener;
- private ModbusSlave MCU_Modbusserver;
-
- private TcpClient PLCTCPClient;
- public ModbusIpMaster PLCModbusMaster;
-
- private Thread MCU_emulator_thread;
- private Thread PLC_emulator_thread;
-
- private string PLC_ip;
- private int PLC_port;
-
- private bool runsimulator = true;
-
- private int distAZ, distEL, currentAZ, currentEL;
-
- public Test_control_pannel(string PLC_ip, string MCU_ip, int MCU_port, int PLC_port)
- {
- // PLCTCPClient = new TcpClient(PLC_ip, PLC_port);
- // PLCModbusMaster = ModbusIpMaster.CreateIp(PLCTCPClient);
- this.PLC_ip = PLC_ip;
- this.PLC_port = PLC_port;
-
- try
- {
- PLC_emulator_thread = new Thread(new ThreadStart(Run_PLC_emulator_thread));
- //MCU_TCPListener = new TcpListener(new IPEndPoint(IPAddress.Parse("127.0.0.2"), 8080));
- //Console.WriteLine(MCU_ip,)
- MCU_TCPListener = new TcpListener(new IPEndPoint(IPAddress.Parse(MCU_ip), MCU_port));
- MCU_emulator_thread = new Thread(new ThreadStart(Run_MCU_server_thread));
- }
- catch (Exception e)
- {
- if ((e is ArgumentNullException) || (e is ArgumentOutOfRangeException))
- {
- Console.WriteLine(e);
- return;
- }
- else { throw e; }// Unexpected exception
- }
- try
- {
- MCU_TCPListener.Start(1);
- }
- catch (Exception e)
- {
- if ((e is SocketException) || (e is ArgumentOutOfRangeException) || (e is InvalidOperationException))
- {
- Console.WriteLine(e);
- return;
- }
- }
- runsimulator = true;
- PLC_emulator_thread.Start();
- MCU_emulator_thread.Start();
- }
-
- public void Bring_down()
- {
- runsimulator = false;
- PLC_emulator_thread.Join();
- MCU_emulator_thread.Join();
- }
-
- private void Run_PLC_emulator_thread()
- {
- while (runsimulator)
- {
- try
- {
- PLCTCPClient = new TcpClient(this.PLC_ip, this.PLC_port);
- PLCModbusMaster = ModbusIpMaster.CreateIp(PLCTCPClient);
- }
- catch
- {//no server setup on control room yet
- Thread.Sleep(10);
- }
- Console.WriteLine("________________PLC sim running");
- PLCModbusMaster.WriteMultipleRegisters((ushort)PLC_modbus_server_register_mapping.Safty_INTERLOCK-1,new ushort[] { 12});
- while (runsimulator)
- {
- Thread.Sleep(50);
- }
- }
-
- }
-
- private void Server_Written_to_handler(object sender, DataStoreEventArgs e)
- {
- MCU_Modbusserver.DataStore.HoldingRegisters[1] = (ushort)(MCU_Modbusserver.DataStore.HoldingRegisters[1] & 0xff7f);
- //Console.WriteLine("plcdriver data writen 1 reg "+ e.Data.B[0]+" start adr "+ e.StartAddress);
- ushort[] data = new ushort[e.Data.B.Count];
- for (int i = 0; i < e.Data.B.Count; i++)
- {
- data[i] = e.Data.B[i];
- }
- handleCMD(data);
- }
-
- private void Run_MCU_server_thread()
- {
- byte slaveId = 1;
- // create and start the TCP slave
- MCU_Modbusserver = ModbusTcpSlave.CreateTcp(slaveId, MCU_TCPListener);
- //coils, inputs, holdingRegisters, inputRegisters
- MCU_Modbusserver.DataStore = DataStoreFactory.CreateDefaultDataStore(0, 0, 1054, 0);
- // PLC_Modbusserver.DataStore.SyncRoot.ToString();
-
- //MCU_Modbusserver.ModbusSlaveRequestReceived += new EventHandler(Server_Read_handler);
- MCU_Modbusserver.DataStore.DataStoreWrittenTo += new EventHandler(Server_Written_to_handler);
-
- MCU_Modbusserver.Listen();
-
- //PLC_Modbusserver.ListenAsync().GetAwaiter().GetResult();
-
- // prevent the main thread from exiting
- ushort[] previos_out, current_out;
- previos_out = Copy_modbus_registers(1025, 20);
- while (runsimulator)
- {
- Thread.Sleep(10);
- }
-
-
- }
-
- private bool handleCMD(ushort[] data)
- {
- string outstr = " inreg";
- for (int v = 0; v < data.Length; v++)
- {
- outstr += Convert.ToString(data[v], 16).PadLeft(5) + ",";
- }
- // Console.WriteLine(outstr);
- if (data[1] == 0x0403)//move cmd
- {
- distAZ = (data[6] << 16) + data[7];
- distEL = (data[12] << 16) + data[13];
- // MCU_Modbusserver.DataStore.HoldingRegisters[3] = data[6];
- // MCU_Modbusserver.DataStore.HoldingRegisters[4] = data[7];
- // MCU_Modbusserver.DataStore.HoldingRegisters[13] = data[12];
- // MCU_Modbusserver.DataStore.HoldingRegisters[14] = data[13];
- //Console.WriteLine("AZ_step2 {0,10} EL_step2 {1,10}", addaz, addel);
- Console.WriteLine("AZ_22 {0,16} EL_22 {1,16}", (MCU_Modbusserver.DataStore.HoldingRegisters[3] << 16) + MCU_Modbusserver.DataStore.HoldingRegisters[4], (MCU_Modbusserver.DataStore.HoldingRegisters[13] << 16) + MCU_Modbusserver.DataStore.HoldingRegisters[14]);
-
- currentAZ += distAZ;
- currentEL += distEL;
-
- MCU_Modbusserver.DataStore.HoldingRegisters[3] = (ushort)((currentAZ & 0xffff0000) >> 16);
- MCU_Modbusserver.DataStore.HoldingRegisters[4] = (ushort)(currentAZ & 0xffff);
- MCU_Modbusserver.DataStore.HoldingRegisters[13] = (ushort)((currentEL & 0xffff0000) >> 16);
- MCU_Modbusserver.DataStore.HoldingRegisters[14] = (ushort)(currentEL & 0xffff);
- MCU_Modbusserver.DataStore.HoldingRegisters[1] = (ushort)(MCU_Modbusserver.DataStore.HoldingRegisters[1] | 0x0080);
-
- Console.WriteLine("AZ_finni1 {0,10} EL_finni1 {1,10}", (MCU_Modbusserver.DataStore.HoldingRegisters[3]<<16)+ MCU_Modbusserver.DataStore.HoldingRegisters[4], (MCU_Modbusserver.DataStore.HoldingRegisters[13] << 16) + MCU_Modbusserver.DataStore.HoldingRegisters[14]);
-
- return true;
- } else if(data[0] == 0x0002 || data[0] == 0x0002) {//move cmd
- MCU_Modbusserver.DataStore.HoldingRegisters[1] = (ushort)(MCU_Modbusserver.DataStore.HoldingRegisters[1] & 0xff7f);
- // AZ_speed = ((data[4] << 16) + data[5]) / 20;
- //AZ_speed = ((data[14] << 16) + data[15]) / 20;
- // acc = data[6];
- distAZ = (data[2] << 16) + data[3];
- distEL = (data[12] << 16) + data[13];
- currentAZ += distAZ;
- currentEL += distEL;
-
- MCU_Modbusserver.DataStore.HoldingRegisters[3] = (ushort)((currentAZ & 0xffff0000) >> 16);
- MCU_Modbusserver.DataStore.HoldingRegisters[4] = (ushort)(currentAZ & 0xffff);
- MCU_Modbusserver.DataStore.HoldingRegisters[13] = (ushort)((currentEL & 0xffff0000) >> 16);
- MCU_Modbusserver.DataStore.HoldingRegisters[14] = (ushort)(currentEL & 0xffff);
- MCU_Modbusserver.DataStore.HoldingRegisters[1] = (ushort)(MCU_Modbusserver.DataStore.HoldingRegisters[1] | 0x0080);
-
- return true;
- }
- return false;
- }
-
- private ushort[] Copy_modbus_registers(int start_index, int length)
- {
- ushort[] data = new ushort[length];
- for (int i = 0; i < length; i++)
- {
- data[i] = MCU_Modbusserver.DataStore.HoldingRegisters[i + start_index];
- }
- return data;
- }
- }
-}
diff --git a/ControlRoomApplication/ControlRoomApplication/Simulators/Hardware/WeatherStation/SimulationWeatherStation.cs b/ControlRoomApplication/ControlRoomApplication/Simulators/Hardware/WeatherStation/SimulationWeatherStation.cs
index bf9c0422..76a05916 100644
--- a/ControlRoomApplication/ControlRoomApplication/Simulators/Hardware/WeatherStation/SimulationWeatherStation.cs
+++ b/ControlRoomApplication/ControlRoomApplication/Simulators/Hardware/WeatherStation/SimulationWeatherStation.cs
@@ -1,27 +1,78 @@
using System;
using ControlRoomApplication.Constants;
+using ControlRoomApplication.Database;
using ControlRoomApplication.Entities;
namespace ControlRoomApplication.Simulators.Hardware.WeatherStation
{
public class SimulationWeatherStation : AbstractWeatherStation
{
+ private static readonly log4net.ILog logger =
+ log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
+
private Random Rand;
+ private DateTime lastRefreshTime;
+
+ private int windDirectionCounter;
+ private String[] windDirections = { "N", "NNE", "NE", "ENE", "E", "ESE", "SE", "SSE", "S",
+ "SSW", "SW", "WSW", "W", "WNW", "NW", "NNW"};
+
+ Weather_Data data;
public SimulationWeatherStation(int currentWindSpeedScanDelayMS)
: base(currentWindSpeedScanDelayMS)
{
Rand = new Random();
+ lastRefreshTime = (DateTime.Now).AddSeconds(-70);
+ windDirectionCounter = 0;
+ data = new Weather_Data(0, " ", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+
+
+ ReloadWeatherDataThread = null;
+ KeepReloadWeatherDataThreadAlive = false;
+ }
+
+
+ private void ReloadData()
+ {
+ // if date and time difference from the last time is more than 30 seconds
+ if ((DateTime.Now - lastRefreshTime).TotalSeconds >= 30)
+ {
+ // redo all the data
+ data.outsideTemp = (float)GetRandomValue(58.44, (91 - 58.44) / 6);
+ data.insideTemp = (float)GetRandomValue(70, (80 - 70) / 6);
+ data.dewPoint = (float)GetRandomValue(48.43, (69 - 48.43) / 6);
+ data.outsideHumidity = (int)GetRandomValue(50, (100 - 50) / 6);
+ data.totalRain = (float)GetRandomValue(42, (54 - 42) / 6);
+ data.dailyRain = (float)GetRandomValue(3.5, (4.5 - 3.5) / 6);
+ data.monthlyRain = (float)GetRandomValue(3.5, (4.5 - 3.5) / 6);
+ data.rainRate = (float)GetRandomValue(0.2, (1 - 0.2) / 6);
+ data.heatIndex = (int)GetRandomValue(74.6, (84.6 - 74.6) / 6);
+ data.windSpeed = (float)GetRandomValue(MiscellaneousHardwareConstants.SIMULATION_WEATHER_STATION_AVERAGE_WIND_SPEED_MPH, MiscellaneousHardwareConstants.SIMULATION_WEATHER_STATION_MAXIMUM_ALLOWABLE_WIND_SPEED_MPH_STD_DEV);
+ data.baromPressure = (float)GetRandomValue(30, (40 - 30) / 6);
+ data.windChill = (float)GetRandomValue(30, (40 - 30) / 6);
+
+ data.windDirection = windDirections[windDirectionCounter];
+ if (++windDirectionCounter >= 16)
+ {
+ windDirectionCounter = 0;
+ }
+
+ DatabaseOperations.AddWeatherData(WeatherData.Generate(data));
+
+ // change the successfull date and time
+ lastRefreshTime = DateTime.Now;
+ }
}
- protected override double ReadCurrentWindSpeedMPH()
+ private double GetRandomValue(double averageValue, double standardDeviation)
{
// Generate a Gaussian random distribution through a Box-Muller transform
double rand1 = 1 - Rand.NextDouble();
double rand2 = 1 - Rand.NextDouble();
double randStdNorm = Math.Sqrt(-2 * Math.Log(rand1)) * Math.Sin(2 * Math.PI * rand2);
- double randNormValue = MiscellaneousHardwareConstants.SIMULATION_WEATHER_STATION_AVERAGE_WIND_SPEED_MPH + (MiscellaneousHardwareConstants.SIMULATION_WEATHER_STATION_MAXIMUM_ALLOWABLE_WIND_SPEED_MPH_STD_DEV * randStdNorm);
+ double randNormValue = averageValue + (standardDeviation * randStdNorm);
if (randNormValue < 0)
{
@@ -31,9 +82,76 @@ protected override double ReadCurrentWindSpeedMPH()
return randNormValue;
}
- protected override bool TestIfComponentIsAlive()
+ public override bool TestIfComponentIsAlive()
{
return true;
}
+
+ public override float GetBarometricPressure()
+ {
+ return data.baromPressure;
+ }
+
+ public override float GetOutsideTemp()
+ {
+ return data.outsideTemp;
+ }
+
+ public override float GetInsideTemp()
+ {
+ return data.insideTemp;
+ }
+
+ public override float GetDewPoint()
+ {
+ return data.dewPoint;
+ }
+
+ public override float GetWindChill()
+ {
+ return data.windChill;
+ }
+
+ public override int GetHumidity()
+ {
+ return (int)data.outsideHumidity;
+ }
+
+ public override float GetTotalRain()
+ {
+ return data.totalRain;
+ }
+
+ public override float GetDailyRain()
+ {
+ return data.dailyRain;
+ }
+
+ public override float GetMonthlyRain()
+ {
+ return data.monthlyRain;
+ }
+
+ public override float GetWindSpeed()
+ {
+ // we call reload data here because this is the only function that is consistently called
+ ReloadData();
+ return data.windSpeed;
+ }
+
+ public override String GetWindDirection()
+ {
+ return data.windDirection;
+ }
+
+ public override float GetRainRate()
+ {
+ return data.rainRate;
+ }
+
+ public override int GetHeatIndex()
+ {
+ return (int)data.heatIndex;
+ }
}
}
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplication/UIDoc.pdf b/ControlRoomApplication/ControlRoomApplication/UIDoc.pdf
new file mode 100644
index 00000000..09bfce40
Binary files /dev/null and b/ControlRoomApplication/ControlRoomApplication/UIDoc.pdf differ
diff --git a/ControlRoomApplication/ControlRoomApplication/Util/Utilities.cs b/ControlRoomApplication/ControlRoomApplication/Util/Utilities.cs
new file mode 100644
index 00000000..651ea4fd
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Util/Utilities.cs
@@ -0,0 +1,93 @@
+using System;
+using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Net;
+using ControlRoomApplication.Constants;
+using ControlRoomApplication.Util;
+using System.Windows.Forms;
+using ControlRoomApplication.Controllers.Communications;
+
+namespace ControlRoomApplication.Util
+{
+
+ public class Utilities
+ {
+ public static object timeZoneName;
+
+ public static String GetTimeStamp()
+ {
+ string timeZone = string.Empty;
+ string timeZoneString = TimeZone.CurrentTimeZone.IsDaylightSavingTime(DateTime.Now)
+ ? TimeZone.CurrentTimeZone.StandardName
+ : TimeZone.CurrentTimeZone.DaylightName;
+
+ string[] timeZoneWords = timeZoneString.Split(' ');
+ foreach (string timeZoneWord in timeZoneWords)
+ {
+ if (timeZoneWord[0] != '(')
+ {
+ timeZone += timeZoneWord[0];
+ }
+ else
+ {
+ timeZone += timeZoneWord;
+ }
+ }
+
+ timeZone = timeZone.ToUpper().Trim();
+ string dateTime = (DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " " + timeZone);
+
+ return dateTime;
+ }
+
+ ///
+ /// This allows us to write to the user interface from a thread other than the thread that created
+ /// the user interface.
+ ///
+ /// The form class name.
+ /// What form class object.
+ /// The code that changes the UI component.
+ public static void WriteToGUIFromThread(T writeTo, Action codeBlock) where T:Form
+ {
+ if (writeTo.InvokeRequired)
+ {
+ IAsyncResult result = writeTo.BeginInvoke(new MethodInvoker(delegate ()
+ {
+ codeBlock();
+ }));
+ }
+ else if (writeTo.IsHandleCreated)
+ {
+ codeBlock();
+ }
+ }
+
+ ///
+ /// Checks if the command sent is using a version of TCP that uses encryption. If so, it decrypts and return the command to be parsed like normal
+ /// If the version of TCP uses encryption, then we must also encrypt the data sent back to the mobile app, hence we change the encrypted flag to true
+ ///
+ ///
+ /// A tuple that contains the either decrypted or unmodified string and a boolean that says whether or not the string was encrypted.
+ public static Tuple CheckEncrypted(string data)
+ {
+ bool encrypted = false;
+ double versionNum;
+
+ if (Double.TryParse(data.Substring(0, data.IndexOf('|')), out versionNum) && versionNum >= 1.1)
+ {
+ // Set the instances encrypted bool to true
+ encrypted = true;
+
+ // Decrypt the command
+ data = AES.Decrypt(data.Substring(data.IndexOf('|') + 1), AESConstants.KEY, AESConstants.IV);
+ }
+
+ return new Tuple(data, encrypted);
+ }
+ }
+}
+
diff --git a/ControlRoomApplication/ControlRoomApplication/Util/Validator.cs b/ControlRoomApplication/ControlRoomApplication/Util/Validator.cs
new file mode 100644
index 00000000..d270893b
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplication/Util/Validator.cs
@@ -0,0 +1,306 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Net;
+using ControlRoomApplication.Constants;
+using System.Net.Sockets;
+
+namespace ControlRoomApplication.Validation {
+
+ public class Validator
+ {
+
+ ///
+ /// Used to determine if a port number is in the acceptable range. Helpful for user validation
+ ///
+ /// port number, as an integer
+ /// true if the port is valid (within acceptable range), otherwise false
+ public static bool ValidatePort(int port)
+ {
+ return (port <= MiscellaneousConstants.MAX_PORT_VALUE
+ && port >= MiscellaneousConstants.MIN_PORT_VALUE);
+
+
+ }
+
+ ///
+ /// Alternate method to handle the case where the input is coming from a text box
+ ///
+ /// text from the textbox to parse
+ /// true if the string is a valid port number, false otherwise
+ public static bool ValidatePort(string text)
+ {
+ int port;
+ int.TryParse(text, out port);
+ // luckily, since port 0 is reserved, we don't need to check if
+ // port would be 0 from the parse failing. It handles both cases!
+ return ValidatePort(port);
+ }
+
+
+ ///
+ /// Validating that a string input by user into IP field is a valid IP Address
+ ///
+ /// string to be converted
+ /// true if the IP is valid, false if the string throws an exception
+ /// meaning it was invalid.
+ public static bool ValidateIPAddress(string ip)
+ {
+ IPAddress address;
+ try {
+ address = IPAddress.Parse(ip);
+ }catch (FormatException e)
+ {
+ Console.WriteLine(e.Message);
+ return false;
+ }
+ catch (ArgumentNullException e)
+ {
+ Console.WriteLine(e.Message);
+ return false;
+ }
+ return true;
+
+ }
+
+
+ ///
+ /// Validating speed from user input in RTControlForm
+ ///
+ /// speed value, given by user in RPMs
+ /// true if the value is between the accepted range, false otherwise
+ public static bool ValidateSpeed(double speed)
+ {
+ return (speed <= MiscellaneousConstants.MAX_SPEED_RPM
+ && speed >= MiscellaneousConstants.MIN_SPEED_RPM);
+ }
+
+ ///
+ /// Helper method to validate via a text box
+ ///
+ /// user text to validate
+ /// returns true, if the textbox speed value is a valid
+ /// double AND is in the expected range. False otherwise
+ public static bool ValidateSpeed(string text)
+ {
+ double speed;
+ try
+ {
+ speed = Double.Parse(text);
+ }
+ catch(FormatException e)
+ {
+ Console.WriteLine(e.Message);
+ return false;
+ }
+ catch (ArgumentNullException e)
+ {
+ Console.WriteLine(e.Message);
+ return false;
+ }
+ return ValidateSpeed(speed);
+ }
+
+ ///
+ /// used to check ONLY if the text is a valid double
+ /// Does NOT account for the speed being in the expected range (use ValidateSpeed(string text) for that)
+ ///
+ ///
+ ///
+ public static bool ValidateSpeedTextOnly(string text)
+ {
+ double speed;
+ try
+ {
+ speed = Double.Parse(text);
+ }
+ catch (FormatException e)
+ {
+ Console.WriteLine(e.Message);
+ return false;
+ }
+ catch (ArgumentNullException e)
+ {
+ Console.WriteLine(e.Message);
+ return false;
+ }
+ return true;
+ }
+
+ ///
+ /// Validating the voltage that the user entered is withing the acceptable range
+ ///
+ /// Valueinput by user, in Volts
+ /// true, if in the expected range, false otherwise
+ public static bool ValidateOffsetVoltage(double volts)
+ {
+ return (volts >= 0 && volts <= 4.095);
+ }
+
+ ///
+ /// Helper method to validate offset voltage via a string (Windows Form textbox will return as a string)
+ /// Also used to validate the voltage that the user entered is withing the acceptable range
+ ///
+ /// the textnox from the windows form,
+ /// or any string of text that contains a voltage value
+ /// true, if the voltage is a valid double AND is in the expected range. False otherwise.
+ public static bool ValidateOffsetVoltage(string text)
+ {
+ double volts;
+ try
+ {
+ volts = Double.Parse(text);
+ }
+ catch (FormatException e)
+ {
+ Console.WriteLine(e.Message);
+ return false;
+ }
+ catch (ArgumentNullException e)
+ {
+ Console.WriteLine(e.Message);
+ return false;
+ }
+ return ValidateOffsetVoltage(volts);
+ }
+
+ ///
+ /// Method to validate the IFGain user input in the RTControl Form.
+ /// Useful when input is a textbox, i.e. from a Windows Form.
+ ///
+ /// The textbox, or any string of text to be validated for IFGain
+ /// true if the value is a valid double AND the IFGain is in the expected range
+ public static bool ValidateIFGain(string text)
+ {
+ double decibles;
+ try
+ {
+ decibles = Double.Parse(text);
+ }
+ catch (FormatException e)
+ {
+ Console.WriteLine(e.Message);
+ return false;
+ }
+ catch (ArgumentNullException e)
+ {
+ Console.WriteLine(e.Message);
+ return false;
+ }
+ return ValidateIFGain(decibles);
+ }
+
+ ///
+ /// Method to validate decibles are in the expected range
+ /// given a valid double. Mainly used for IFGain user input in the RTControl Form
+ ///
+ /// Decibles entered by the user
+ /// True, if the decibles are in the expected range. False otherwise
+ public static bool ValidateIFGain(double decibles)
+ {
+ return (decibles >= 10.00 && decibles <= 25.75);
+ }
+
+ ///
+ /// Method to validate frequency from a string of text. Will attempt to parse
+ /// the double out of the string, then validate the double is within the expected frequency range.
+ ///
+ /// String of text entered by user, or any string of text to be
+ /// validated for frequency
+ /// If unable to parse, or the double parsed is not in the expected
+ /// range, it will return false. True otherwise
+ public static bool ValidateFrequency(string text)
+ {
+ double hertz;
+ try
+ {
+ hertz = Double.Parse(text);
+ }
+ catch (FormatException e)
+ {
+ Console.WriteLine(e.Message);
+ return false;
+ }
+ catch (ArgumentNullException e)
+ {
+ Console.WriteLine(e.Message);
+ return false;
+ }
+ return ValidateFrequency(hertz);
+ }
+
+ ///
+ /// Method to validate frequency entered by user, or any value of frequency
+ ///
+ /// frequency, in hertz, as a double value
+ /// True, if the frequency is within the accepted range. False otherwise
+ public static bool ValidateFrequency(double hertz)
+ {
+ return (hertz >= 0.0);
+ }
+
+ ///
+ /// This is used to determine if a string value can be parsed into a double.
+ ///
+ ///
+ /// True if it is a valid double, false otherwise.
+ public static bool IsDouble(string text)
+ {
+ try
+ {
+ double.Parse(text);
+ return true;
+ }
+ catch
+ {
+ return false;
+ }
+ }
+
+ ///
+ /// This is used to validate if a value is in between two values. Null can be passed through
+ /// the lower or upper bounds if a lower or upper bound is not necessary.
+ ///
+ /// The value being assessed.
+ /// The valid lower bound of the value.
+ /// The valid upper bound of the value.
+ ///
+ public static bool IsBetween(double value, double? lower, double? upper)
+ {
+ if (lower != null && value < lower) return false;
+
+ if (upper != null && value > upper) return false;
+
+ return true;
+ }
+
+ ///
+ /// This verifies that a server is currently running on an IP address and port combo.
+ ///
+ /// IP address that we are verifying.
+ /// Port that we are verifying.
+ ///
+ public static bool ServerRunningOnIp(string ip, int port)
+ {
+ bool success = false;
+ TcpClient c = new TcpClient();
+ try
+ {
+ c.Connect(ip, port);
+ success = true;
+ }
+ catch {
+ success = false;
+ }
+
+ c.Close();
+ c.Dispose();
+
+ return success;
+ }
+ }
+
+}
+
diff --git a/ControlRoomApplication/ControlRoomApplication/VantageProDll242/CP210xManufacturing.dll b/ControlRoomApplication/ControlRoomApplication/VantageProDll242/CP210xManufacturing.dll
new file mode 100644
index 00000000..87c3b277
Binary files /dev/null and b/ControlRoomApplication/ControlRoomApplication/VantageProDll242/CP210xManufacturing.dll differ
diff --git a/ControlRoomApplication/ControlRoomApplication/VantageProDll242/SiUSBXp.dll b/ControlRoomApplication/ControlRoomApplication/VantageProDll242/SiUSBXp.dll
new file mode 100644
index 00000000..64aaaabe
Binary files /dev/null and b/ControlRoomApplication/ControlRoomApplication/VantageProDll242/SiUSBXp.dll differ
diff --git a/ControlRoomApplication/ControlRoomApplication/VantageProDll242/VantagePro.dll b/ControlRoomApplication/ControlRoomApplication/VantageProDll242/VantagePro.dll
new file mode 100644
index 00000000..1fb8303e
Binary files /dev/null and b/ControlRoomApplication/ControlRoomApplication/VantageProDll242/VantagePro.dll differ
diff --git a/ControlRoomApplication/ControlRoomApplication/YCASIcon.ico b/ControlRoomApplication/ControlRoomApplication/YCASIcon.ico
new file mode 100644
index 00000000..577129f3
Binary files /dev/null and b/ControlRoomApplication/ControlRoomApplication/YCASIcon.ico differ
diff --git a/ControlRoomApplication/ControlRoomApplication/packages.config b/ControlRoomApplication/ControlRoomApplication/packages.config
index 24359a12..5dd1e68f 100644
--- a/ControlRoomApplication/ControlRoomApplication/packages.config
+++ b/ControlRoomApplication/ControlRoomApplication/packages.config
@@ -1,20 +1,48 @@
-
-
-
-
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/App.config b/ControlRoomApplication/ControlRoomApplicationTest/App.config
index 32e50a9a..152e3ad4 100644
--- a/ControlRoomApplication/ControlRoomApplicationTest/App.config
+++ b/ControlRoomApplication/ControlRoomApplicationTest/App.config
@@ -59,6 +59,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/CommunicationTests/AESTest.cs b/ControlRoomApplication/ControlRoomApplicationTest/CommunicationTests/AESTest.cs
new file mode 100644
index 00000000..2e516b7e
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplicationTest/CommunicationTests/AESTest.cs
@@ -0,0 +1,35 @@
+using ControlRoomApplication.Constants;
+using ControlRoomApplication.Controllers.Communications;
+using ControlRoomApplication.Util;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ControlRoomApplicationTest.CommunicationTests
+{
+ [TestClass]
+ public class AESTest
+ {
+ [TestMethod]
+ public void TestEncryptionDecryption()
+ {
+ string rawText = "1.1|SCRIPT|FULL_CLOCK|2022-03-16T20:18:03.636Z";
+ string decrypted = AES.Decrypt(AES.Encrypt(rawText, AESConstants.KEY, AESConstants.IV), AESConstants.KEY, AESConstants.IV);
+
+ Assert.IsTrue(rawText.Equals(decrypted));
+ }
+
+ [TestMethod]
+ public void TestRemoteDecryption()
+ {
+ string command = "1.1|STOP_RT|2022-03-20T22:15:03.660Z";
+ string encrypted = "AA9uv3O7ov+eZ2xM9478QpgOxSBhBbyYMf21krHQMZLAdnaAqGwJ2GkZcT8hxE7T";
+ string decrypted = AES.Decrypt(encrypted, AESConstants.KEY, AESConstants.IV);
+
+ Assert.IsTrue(decrypted.Equals(command));
+ }
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/CommunicationTests/DataToCSVTest.cs b/ControlRoomApplication/ControlRoomApplicationTest/CommunicationTests/DataToCSVTest.cs
new file mode 100644
index 00000000..536459e8
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplicationTest/CommunicationTests/DataToCSVTest.cs
@@ -0,0 +1,65 @@
+using ControlRoomApplication.Controllers.Communications;
+using ControlRoomApplication.Entities;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System;
+using System.Collections.Generic;
+using System.IO;
+
+namespace ControlRoomApplicationTest.CommunicationTests
+{
+ [TestClass]
+ public class DataToCSVTest
+ {
+
+ [TestInitialize]
+ public void TestInit()
+ {
+ string currentPath = AppDomain.CurrentDomain.BaseDirectory;
+ string folderName = "DeleteCSVTestResults";
+ string pathString = Path.Combine(currentPath, folderName);
+ Directory.CreateDirectory(pathString);
+ }
+
+ [TestMethod]
+ public void TestConvertDataToCSV()
+ {
+ string testpath = $"{Path.Combine(AppDomain.CurrentDomain.BaseDirectory, $@".\DeleteCSVTestResults\test-out-{System.DateTime.Now.ToString("yyyyMMddHHmmss")}")}";
+ RFData junk1 = new RFData();
+ junk1.Id = 0;
+ junk1.appointment_id = 0;
+ junk1.TimeCaptured = new DateTime();
+ junk1.Intensity = 10000;
+
+ RFData junk2 = new RFData();
+ junk2.Id = 1;
+ junk2.appointment_id = 0;
+ junk2.TimeCaptured = new DateTime();
+ junk2.Intensity = 20000;
+
+ List JunkRFData = new List();
+ JunkRFData.Add(junk1);
+ JunkRFData.Add(junk2);
+
+ Assert.IsTrue(DataToCSV.ExportToCSV(JunkRFData, testpath));
+ }
+
+ [TestMethod]
+ public void TestDeleteCSV()
+ {
+ string testpath = $"{Path.Combine(AppDomain.CurrentDomain.BaseDirectory, $@".\DeleteCSVTestResults\test-out-{System.DateTime.Now.ToString("yyyyMMddHHmmss")}")}";
+ FileStream file = File.Create(testpath);
+ file.Close();
+
+ Assert.IsTrue(DataToCSV.DeleteCSVFileWhenDone(testpath));
+ }
+
+ [TestCleanup]
+ public void Cleanup()
+ {
+ string currentPath = AppDomain.CurrentDomain.BaseDirectory;
+ string folderName = "DeleteCSVTestResults";
+ string pathString = Path.Combine(currentPath, folderName);
+ Directory.Delete(pathString, true);
+ }
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/CommunicationTests/EmailNotificationTests.cs b/ControlRoomApplication/ControlRoomApplicationTest/CommunicationTests/EmailNotificationTests.cs
new file mode 100644
index 00000000..7c611f23
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplicationTest/CommunicationTests/EmailNotificationTests.cs
@@ -0,0 +1,106 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Threading;
+using System.Text;
+using System.Threading.Tasks;
+using ControlRoomApplication.Controllers.Communications;
+using ControlRoomApplication.Entities;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace ControlRoomApplicationTest.CommunicationTests
+{
+ [TestClass]
+ public class EmailNotificationTests
+ {
+
+ public static string testfileloc;
+
+ [TestInitialize]
+ public void TestInit()
+ {
+ testfileloc = $"test-out-{System.DateTime.Now.ToString("yyyyMMddHHmmss")}";
+ string currentPath = AppDomain.CurrentDomain.BaseDirectory;
+ string folderName = "PushNotificationTestResults";
+ string pathString = Path.Combine(currentPath, folderName);
+ Directory.CreateDirectory(pathString);
+ }
+
+ [TestMethod]
+ public void TestSendingEmailToAllAdmins()
+ {
+ string sender = "SystemTest@ycpradiotelescope.com";
+ string subject = "Amazon SES Test";
+ string body = "AmazonSES Test (.NET)\r\nThis email was sent through AmazonSES using the AWS SDK for .NET.";
+
+ // Execute task
+ Task task = EmailNotifications.sendToAllAdmins(subject, body, sender, true);
+
+ // Wait for main task to finish before assertion
+ task.Wait();
+
+ Assert.IsTrue(task.Result);
+ }
+
+ [TestMethod]
+ public void TestSendingEmailToUser()
+ {
+ string sender = "SystemTest@ycpradiotelescope.com";
+ string subject = "Amazon SES Test";
+ string body = "AmazonSES Test (.NET)\r\nThis email was sent through AmazonSES using the AWS SDK for .NET.";
+ User fakeUser = new User("Test", "User", "testradiotelescopeuser@ycp.edu", NotificationTypeEnum.ALL);
+
+ // Execute task
+ Task task = EmailNotifications.sendToUser(fakeUser, subject, body, sender, null, true);
+
+ // Wait for main task to finish before assertion
+ task.Wait();
+
+ Assert.IsTrue(task.Result);
+ }
+
+ [TestMethod]
+ public void TestSendingEmailWithAttachment()
+ {
+ string testpath = $"{Path.Combine(AppDomain.CurrentDomain.BaseDirectory, $@".\PushNotificationTestResults\test-out-{System.DateTime.Now.ToString("yyyyMMddHHmmss")}")}";
+
+ string sender = "SystemTest@ycpradiotelescope.com";
+ string subject = "Amazon SES Test WITH ATTACHMENT";
+ string body = "AmazonSES Test (.NET) with Attachment\r\nThis email and its attachment were sent through AmazonSES using the AWS SDK for .NET.";
+
+ // If you want to actually get emails while testing, change the email address below to whatever one you want to receive at.
+ // This was already done earlier.
+ User fakeUser = new User("Test", "User", "testradiotelescopeuser@ycp.edu", NotificationTypeEnum.ALL);
+
+ // Gather dummy data
+ RFData junkdata = new RFData();
+ junkdata.Id = 0;
+ junkdata.appointment_id = 0;
+ junkdata.TimeCaptured = System.DateTime.Now;
+ junkdata.Intensity = 8675309;
+
+ List JunkRFData = new List();
+ JunkRFData.Add(junkdata);
+
+ DataToCSV.ExportToCSV(JunkRFData, testpath);
+
+ // Execute task
+ Task task = EmailNotifications.sendToUser(fakeUser, subject, body, sender, $"{testpath}.csv", true);
+
+ // Wait for main task to finish before assertion
+ task.Wait();
+
+ Assert.IsTrue(task.Result);
+ }
+
+ [TestCleanup]
+ public void Cleanup()
+ {
+ string currentPath = AppDomain.CurrentDomain.BaseDirectory;
+ string folderName = "PushNotificationTestResults";
+ string pathString = Path.Combine(currentPath, folderName);
+
+ Directory.Delete(pathString, true);
+ }
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/CommunicationTests/PushNotificationTest.cs b/ControlRoomApplication/ControlRoomApplicationTest/CommunicationTests/PushNotificationTest.cs
new file mode 100644
index 00000000..21872448
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplicationTest/CommunicationTests/PushNotificationTest.cs
@@ -0,0 +1,22 @@
+using ControlRoomApplication.Controllers.Communications;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System.Threading.Tasks;
+
+namespace ControlRoomApplicationTest.CommunicationTests
+{
+ [TestClass]
+ public class PushNotificationTest
+ {
+ [TestMethod]
+ public void TestSendPushNotificationsToAllAdmins()
+ {
+ // Execute task
+ Task task = pushNotification.sendToAllAdmins("TEST", "This should pass.", true);
+
+ // Wait for task to complete so result is up to date
+ task.Wait();
+
+ Assert.IsTrue(task.Result);
+ }
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/CommunicationTests/RemoteListenerTest.cs b/ControlRoomApplication/ControlRoomApplicationTest/CommunicationTests/RemoteListenerTest.cs
new file mode 100644
index 00000000..7a86f3d8
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplicationTest/CommunicationTests/RemoteListenerTest.cs
@@ -0,0 +1,759 @@
+using ControlRoomApplication.Constants;
+using ControlRoomApplication.Controllers;
+using ControlRoomApplication.Controllers.Communications;
+using ControlRoomApplication.Controllers.Communications.Enumerations;
+using ControlRoomApplication.Controllers.PLCCommunication.PLCDrivers.MCUManager.Enumerations;
+using ControlRoomApplication.Controllers.SensorNetwork;
+using ControlRoomApplication.Database;
+using ControlRoomApplication.Entities;
+using ControlRoomApplication.Simulators.Hardware.WeatherStation;
+using ControlRoomApplication.Util;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Net.Sockets;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace ControlRoomApplicationTest.CommunicationTests
+{
+ [TestClass]
+ public class RemoteListenerTest
+ {
+ // This will contain the RemoteListener object we are using for the various tests
+ PrivateObject PrivListener;
+
+ ControlRoom ControlRoom;
+
+ RadioTelescopeController RtController;
+ RadioTelescope RadioTelescope;
+
+ // PLC driver
+ readonly string PlcIp = "127.0.0.1";
+ readonly int PlcPort = 4000;
+ readonly string McuIp = "127.0.0.1";
+ readonly int McuPort = 4001;
+
+ // Sensor Network
+ readonly IPAddress SnServerIp = IPAddress.Parse("127.0.0.1");
+ readonly int SnServerPort = 3000;
+ readonly string SnClientIp = "127.0.0.1";
+ readonly int SnClientPort = 3001;
+ readonly int SnTelescopeId = 3000;
+
+ [TestInitialize]
+ public void Initialize()
+ {
+ RadioTelescope = new RadioTelescope();
+
+ AbstractPLCDriver PLC = new SimulationPLCDriver(PlcIp, McuIp, McuPort, PlcPort, true, false);
+ RadioTelescope.PLCDriver = PLC;
+
+ SensorNetworkServer SN = new SensorNetworkServer(SnServerIp, SnServerPort, SnClientIp, SnClientPort, SnTelescopeId, true);
+ RadioTelescope.SensorNetworkServer = SN;
+
+ RtController = new RadioTelescopeController(RadioTelescope);
+
+ AbstractWeatherStation WS = new SimulationWeatherStation(1000);
+
+ ControlRoom = new ControlRoom(WS, 80);
+
+ ControlRoom.mobileControlServer.rtController = RtController;
+
+ PrivListener = new PrivateObject(ControlRoom.mobileControlServer);
+ }
+
+ [TestCleanup]
+ public void Cleanup()
+ {
+ // Until a proper bring-down method is created for the Remote Listener, we must stop the server like this after
+ // every test.
+ ((TcpListener)PrivListener.GetFieldOrProperty("server")).Stop();
+
+ DatabaseOperations.DeleteSensorNetworkConfig(RadioTelescope.SensorNetworkServer.InitializationClient.SensorNetworkConfig);
+ }
+
+ [TestMethod]
+ public void TestProcessMessage_SensorInit_RebootsSensorNetworkWithNewInit()
+ {
+ // Create and start SensorNetwork
+ RadioTelescope.SensorNetworkServer.StartSensorMonitoringRoutine();
+
+ // Build command to disable all sensors and set the timeouts to specific values
+ byte expectedDisabled = 0;
+ int expectedDataTimeout = 6;
+ int expectedInitTimeout = 5;
+ string command = "1.0 | SENSOR_INIT | " +
+ $"{expectedDisabled}," +
+ $"{expectedDisabled}," +
+ $"{expectedDisabled}," +
+ $"{expectedDisabled}," +
+ $"{expectedDisabled}," +
+ $"{expectedDisabled}," +
+ $"{expectedDisabled}," +
+ $"{expectedDataTimeout}," +
+ $"{expectedInitTimeout}" + "| 12:00:00";
+
+ ParseTCPCommandResult result = (ParseTCPCommandResult)PrivListener.Invoke("ParseRLString", command);
+ ExecuteTCPCommandResult mvmtResult = (ExecuteTCPCommandResult)PrivListener.Invoke("ExecuteRLCommand", new object[] { result.parsedString });
+ byte[] resultInitBytes = RadioTelescope.SensorNetworkServer.InitializationClient.SensorNetworkConfig.GetSensorInitAsBytes();
+ int resultDataTimeout = RadioTelescope.SensorNetworkServer.InitializationClient.SensorNetworkConfig.TimeoutDataRetrieval / 1000; // ms to seconds
+ int resultInitTimeout = RadioTelescope.SensorNetworkServer.InitializationClient.SensorNetworkConfig.TimeoutInitialization / 1000; // ms to seconds
+
+ Assert.AreEqual(result.parseTCPCommandResultEnum, ParseTCPCommandResultEnum.Success);
+
+
+ // Verify the init values are as expected
+ Assert.AreEqual(expectedDisabled, resultInitBytes[(int)SensorInitializationEnum.ElevationTemp]);
+ Assert.AreEqual(expectedDisabled, resultInitBytes[(int)SensorInitializationEnum.AzimuthTemp]);
+ Assert.AreEqual(expectedDisabled, resultInitBytes[(int)SensorInitializationEnum.ElevationEncoder]);
+ Assert.AreEqual(expectedDisabled, resultInitBytes[(int)SensorInitializationEnum.AzimuthEncoder]);
+ Assert.AreEqual(expectedDisabled, resultInitBytes[(int)SensorInitializationEnum.AzimuthAccelerometer]);
+ Assert.AreEqual(expectedDisabled, resultInitBytes[(int)SensorInitializationEnum.ElevationEncoder]);
+ Assert.AreEqual(expectedDisabled, resultInitBytes[(int)SensorInitializationEnum.CounterbalanceAccelerometer]);
+
+ // Verify init values are as expected
+ Assert.AreEqual(expectedDataTimeout, resultDataTimeout);
+ Assert.AreEqual(expectedInitTimeout, resultInitTimeout);
+
+ // Bring down the server and delete config
+ RadioTelescope.SensorNetworkServer.EndSensorMonitoringRoutine();
+ }
+
+ [TestMethod]
+ public void TestProcessMessage_SensorInitInvalidMessage_Fail()
+ {
+ string invalidCommand = "1.0 | SENSOR_INIT | 0,1,2,3,4 | 12:00:00";
+
+ ParseTCPCommandResult result = (ParseTCPCommandResult)PrivListener.Invoke("ParseRLString", invalidCommand);
+
+ Assert.AreEqual(result.parseTCPCommandResultEnum, ParseTCPCommandResultEnum.MissingCommandArgs);
+ }
+
+ [TestMethod]
+ public void TestProcessMessage_SetOverrideSetCounterbalanceAcc_SetsCounterbalanceOverride()
+ {
+ string command = "1.0 | SET_OVERRIDE | CB_ACC | TRUE | 12:00:00";
+
+ ParseTCPCommandResult result = (ParseTCPCommandResult)PrivListener.Invoke("ParseRLString", command);
+ ExecuteTCPCommandResult mvmtResult = (ExecuteTCPCommandResult)PrivListener.Invoke("ExecuteRLCommand", new object[] { result.parsedString });
+
+ Assert.AreEqual(result.parseTCPCommandResultEnum, ParseTCPCommandResultEnum.Success);
+ Assert.AreEqual(mvmtResult.movementResult, MovementResult.Success);
+ Assert.IsTrue(RtController.overrides.overrideCounterbalanceAccelerometer);
+ }
+
+ [TestMethod]
+ public void TestProcessMessage_SetOverrideRemCounterbalanceAcc_RemovesCounterbalanceOverride()
+ {
+ string command = "1.0 | SET_OVERRIDE | CB_ACC | FALSE | 12:00:00";
+
+ ParseTCPCommandResult result = (ParseTCPCommandResult)PrivListener.Invoke("ParseRLString", command);
+ ExecuteTCPCommandResult mvmtResult = (ExecuteTCPCommandResult)PrivListener.Invoke("ExecuteRLCommand", new object[] { result.parsedString });
+
+ Assert.AreEqual(result.parseTCPCommandResultEnum, ParseTCPCommandResultEnum.Success);
+ Assert.AreEqual(mvmtResult.movementResult, MovementResult.Success);
+ Assert.IsFalse(RtController.overrides.overrideCounterbalanceAccelerometer);
+ }
+
+ [TestMethod]
+ public void TestProcessMessage_SetOverrideSetElevationAcc_SetsElevationAccOverride()
+ {
+ string command = "1.0 | SET_OVERRIDE | EL_ACC | TRUE | 12:00:00";
+
+ ParseTCPCommandResult result = (ParseTCPCommandResult)PrivListener.Invoke("ParseRLString", command);
+ ExecuteTCPCommandResult mvmtResult = (ExecuteTCPCommandResult)PrivListener.Invoke("ExecuteRLCommand", new object[] { result.parsedString });
+
+
+ Assert.AreEqual(result.parseTCPCommandResultEnum, ParseTCPCommandResultEnum.Success);
+ Assert.AreEqual(mvmtResult.movementResult, MovementResult.Success);
+ Assert.IsTrue(RtController.overrides.overrideElevationAccelerometer);
+ }
+
+ [TestMethod]
+ public void TestProcessMessage_SetOverrideRemElevationAcc_RemovesElevationAccOverride()
+ {
+ string command = "1.0 | SET_OVERRIDE | EL_ACC | FALSE | 12:00:00";
+
+ ParseTCPCommandResult result = (ParseTCPCommandResult)PrivListener.Invoke("ParseRLString", command);
+ ExecuteTCPCommandResult mvmtResult = (ExecuteTCPCommandResult)PrivListener.Invoke("ExecuteRLCommand", new object[] { result.parsedString });
+
+
+ Assert.AreEqual(result.parseTCPCommandResultEnum, ParseTCPCommandResultEnum.Success);
+ Assert.AreEqual(mvmtResult.movementResult, MovementResult.Success);
+ Assert.IsFalse(RtController.overrides.overrideElevationAccelerometer);
+ }
+
+ [TestMethod]
+ public void TestProcessMessage_SetOverrideSetAzimuthAcc_SetsAzimuthAccOverride()
+ {
+ string command = "1.0 | SET_OVERRIDE | AZ_ACC | TRUE | 12:00:00";
+
+ ParseTCPCommandResult result = (ParseTCPCommandResult)PrivListener.Invoke("ParseRLString", command);
+ ExecuteTCPCommandResult mvmtResult = (ExecuteTCPCommandResult)PrivListener.Invoke("ExecuteRLCommand", new object[] { result.parsedString });
+
+
+ Assert.AreEqual(result.parseTCPCommandResultEnum, ParseTCPCommandResultEnum.Success);
+ Assert.AreEqual(mvmtResult.movementResult, MovementResult.Success);
+ Assert.IsTrue(RtController.overrides.overrideAzimuthAccelerometer);
+ }
+
+ [TestMethod]
+ public void TestProcessMessage_SetOverrideRemAzimuthAcc_RemovesAzimuthAccOverride()
+ {
+ string command = "1.0 | SET_OVERRIDE | AZ_ACC | FALSE | 12:00:00";
+
+ ParseTCPCommandResult result = (ParseTCPCommandResult)PrivListener.Invoke("ParseRLString", command);
+ ExecuteTCPCommandResult mvmtResult = (ExecuteTCPCommandResult)PrivListener.Invoke("ExecuteRLCommand", new object[] { result.parsedString });
+
+
+ Assert.AreEqual(result.parseTCPCommandResultEnum, ParseTCPCommandResultEnum.Success);
+ Assert.AreEqual(mvmtResult.movementResult, MovementResult.Success);
+ Assert.IsFalse(RtController.overrides.overrideAzimuthAccelerometer);
+ }
+
+ [TestMethod]
+ public void TestProcessMessage_SetOverrideSetElevationEnc_SetsElevationEncOverride()
+ {
+ string command = "1.0 | SET_OVERRIDE | EL_ABS_ENC | TRUE | 12:00:00";
+
+ ParseTCPCommandResult result = (ParseTCPCommandResult)PrivListener.Invoke("ParseRLString", command);
+ ExecuteTCPCommandResult mvmtResult = (ExecuteTCPCommandResult)PrivListener.Invoke("ExecuteRLCommand", new object[] { result.parsedString });
+
+
+ Assert.AreEqual(result.parseTCPCommandResultEnum, ParseTCPCommandResultEnum.Success);
+ Assert.AreEqual(mvmtResult.movementResult, MovementResult.Success);
+ Assert.IsTrue(RtController.overrides.overrideElevationAbsEncoder);
+ }
+
+ [TestMethod]
+ public void TestProcessMessage_SetOverrideRemElevationEnc_RemovesElevationEncOverride()
+ {
+ string command = "1.0 | SET_OVERRIDE | EL_ABS_ENC | FALSE | 12:00:00";
+
+ ParseTCPCommandResult result = (ParseTCPCommandResult)PrivListener.Invoke("ParseRLString", command);
+ ExecuteTCPCommandResult mvmtResult = (ExecuteTCPCommandResult)PrivListener.Invoke("ExecuteRLCommand", new object[] { result.parsedString });
+
+
+ Assert.AreEqual(result.parseTCPCommandResultEnum, ParseTCPCommandResultEnum.Success);
+ Assert.AreEqual(mvmtResult.movementResult, MovementResult.Success);
+ Assert.IsFalse(RtController.overrides.overrideElevationAbsEncoder);
+ }
+
+ [TestMethod]
+ public void TestProcessMessage_SetOverrideSetAzimuthEnc_SetsAzimuthEncOverride()
+ {
+ string command = "1.0 | SET_OVERRIDE | AZ_ABS_ENC | TRUE | 12:00:00";
+
+ ParseTCPCommandResult result = (ParseTCPCommandResult)PrivListener.Invoke("ParseRLString", command);
+ ExecuteTCPCommandResult mvmtResult = (ExecuteTCPCommandResult)PrivListener.Invoke("ExecuteRLCommand", new object[] { result.parsedString });
+
+ Assert.AreEqual(result.parseTCPCommandResultEnum, ParseTCPCommandResultEnum.Success);
+ Assert.AreEqual(mvmtResult.movementResult, MovementResult.Success);
+ Assert.IsTrue(RtController.overrides.overrideAzimuthAbsEncoder);
+ }
+
+ [TestMethod]
+ public void TestProcessMessage_SetOverrideRemAzimuthEnc_RemovesAzimuthEncOverride()
+ {
+ string command = "1.0 | SET_OVERRIDE | AZ_ABS_ENC | FALSE | 12:00:00";
+
+ ParseTCPCommandResult result = (ParseTCPCommandResult)PrivListener.Invoke("ParseRLString", command);
+ ExecuteTCPCommandResult mvmtResult = (ExecuteTCPCommandResult)PrivListener.Invoke("ExecuteRLCommand", new object[] { result.parsedString });
+
+ Assert.AreEqual(result.parseTCPCommandResultEnum, ParseTCPCommandResultEnum.Success);
+ Assert.AreEqual(mvmtResult.movementResult, MovementResult.Success);
+ Assert.IsFalse(RtController.overrides.overrideAzimuthAbsEncoder);
+ }
+
+ [TestMethod]
+ public void TestProcessMessage_SetOverrideSetElProx90_SetsElProx90Override()
+ {
+ string command = "1.0 | SET_OVERRIDE | ELEVATION_LIMIT_90 | TRUE | 12:00:00";
+
+ ParseTCPCommandResult result = (ParseTCPCommandResult)PrivListener.Invoke("ParseRLString", command);
+ ExecuteTCPCommandResult mvmtResult = (ExecuteTCPCommandResult)PrivListener.Invoke("ExecuteRLCommand", new object[] { result.parsedString });
+
+ Assert.AreEqual(result.parseTCPCommandResultEnum, ParseTCPCommandResultEnum.Success);
+ Assert.AreEqual(mvmtResult.movementResult, MovementResult.Success);
+ Assert.IsTrue(RtController.overrides.overrideElevatProx90);
+ }
+
+ [TestMethod]
+ public void TestProcessMessage_SetOverrideRemElProx90_RemovesElProx90Override()
+ {
+ string command = "1.0 | SET_OVERRIDE | ELEVATION_LIMIT_90 | FALSE | 12:00:00";
+
+ ParseTCPCommandResult result = (ParseTCPCommandResult)PrivListener.Invoke("ParseRLString", command);
+ ExecuteTCPCommandResult mvmtResult = (ExecuteTCPCommandResult)PrivListener.Invoke("ExecuteRLCommand", new object[] { result.parsedString });
+
+ Assert.AreEqual(result.parseTCPCommandResultEnum, ParseTCPCommandResultEnum.Success);
+ Assert.AreEqual(mvmtResult.movementResult, MovementResult.Success);
+ Assert.IsFalse(RtController.overrides.overrideElevatProx90);
+ }
+
+ [TestMethod]
+ public void TestProcessMessage_SetOverrideSetElProx0_SetsElProx0Override()
+ {
+ string command = "1.0 | SET_OVERRIDE | ELEVATION_LIMIT_0 | TRUE | 12:00:00";
+
+ ParseTCPCommandResult result = (ParseTCPCommandResult)PrivListener.Invoke("ParseRLString", command);
+ ExecuteTCPCommandResult mvmtResult = (ExecuteTCPCommandResult)PrivListener.Invoke("ExecuteRLCommand", new object[] { result.parsedString });
+
+ Assert.AreEqual(result.parseTCPCommandResultEnum, ParseTCPCommandResultEnum.Success);
+ Assert.AreEqual(mvmtResult.movementResult, MovementResult.Success);
+ Assert.IsTrue(RtController.overrides.overrideElevatProx0);
+ }
+
+ [TestMethod]
+ public void TestProcessMessage_SetOverrideSetAzMotTemp_SetsAzMotTempOverride()
+ {
+ string command = "1.0 | SET_OVERRIDE | AZIMUTH_MOT_TEMP | TRUE | 12:00:00";
+
+ ParseTCPCommandResult result = (ParseTCPCommandResult)PrivListener.Invoke("ParseRLString", command);
+ ExecuteTCPCommandResult mvmtResult = (ExecuteTCPCommandResult)PrivListener.Invoke("ExecuteRLCommand", new object[] { result.parsedString });
+
+ Assert.AreEqual(result.parseTCPCommandResultEnum, ParseTCPCommandResultEnum.Success);
+ Assert.AreEqual(mvmtResult.movementResult, MovementResult.Success);
+ Assert.IsTrue(RtController.overrides.overrideAzimuthMotTemp);
+ }
+
+ [TestMethod]
+ public void TestProcessMessage_SetOverrideRemAzMotTemp_RemovesAzMotTempOverride()
+ {
+ string command = "1.0 | SET_OVERRIDE | AZIMUTH_MOT_TEMP | FALSE | 12:00:00";
+
+ ParseTCPCommandResult result = (ParseTCPCommandResult)PrivListener.Invoke("ParseRLString", command);
+ ExecuteTCPCommandResult mvmtResult = (ExecuteTCPCommandResult)PrivListener.Invoke("ExecuteRLCommand", new object[] { result.parsedString });
+
+ Assert.AreEqual(result.parseTCPCommandResultEnum, ParseTCPCommandResultEnum.Success);
+ Assert.AreEqual(mvmtResult.movementResult, MovementResult.Success);
+ Assert.IsFalse(RtController.overrides.overrideAzimuthMotTemp);
+ }
+
+ [TestMethod]
+ public void TestProcessMessage_SetOverrideSetElMotTemp_SetsElMotTempOverride()
+ {
+ string command = "1.0 | SET_OVERRIDE | ELEVATION_MOT_TEMP | TRUE | 12:00:00";
+
+ ParseTCPCommandResult result = (ParseTCPCommandResult)PrivListener.Invoke("ParseRLString", command);
+ ExecuteTCPCommandResult mvmtResult = (ExecuteTCPCommandResult)PrivListener.Invoke("ExecuteRLCommand", new object[] { result.parsedString });
+
+ Assert.AreEqual(result.parseTCPCommandResultEnum, ParseTCPCommandResultEnum.Success);
+ Assert.AreEqual(mvmtResult.movementResult, MovementResult.Success);
+ Assert.IsTrue(RtController.overrides.overrideElevatMotTemp);
+ }
+
+ [TestMethod]
+ public void TestProcessMessage_SetOverrideRemElMotTemp_RemovesElMotTempOverride()
+ {
+ string command = "1.0 | SET_OVERRIDE | ELEVATION_MOT_TEMP | FALSE | 12:00:00";
+
+ ParseTCPCommandResult result = (ParseTCPCommandResult)PrivListener.Invoke("ParseRLString", command);
+ ExecuteTCPCommandResult mvmtResult = (ExecuteTCPCommandResult)PrivListener.Invoke("ExecuteRLCommand", new object[] { result.parsedString });
+
+ Assert.AreEqual(result.parseTCPCommandResultEnum, ParseTCPCommandResultEnum.Success);
+ Assert.AreEqual(mvmtResult.movementResult, MovementResult.Success);
+ Assert.IsFalse(RtController.overrides.overrideElevatMotTemp);
+ }
+
+ [TestMethod]
+ public void TestProcessMessage_SetOverrideSetGate_SetsGateOverride()
+ {
+ string command = "1.0 | SET_OVERRIDE | MAIN_GATE | TRUE | 12:00:00";
+
+ ParseTCPCommandResult result = (ParseTCPCommandResult)PrivListener.Invoke("ParseRLString", command);
+ ExecuteTCPCommandResult mvmtResult = (ExecuteTCPCommandResult)PrivListener.Invoke("ExecuteRLCommand", new object[] { result.parsedString });
+
+ Assert.AreEqual(result.parseTCPCommandResultEnum, ParseTCPCommandResultEnum.Success);
+ Assert.AreEqual(mvmtResult.movementResult, MovementResult.Success);
+ Assert.IsTrue(RtController.overrides.overrideGate);
+ }
+
+ [TestMethod]
+ public void TestProcessMessage_SetOverrideRemGate_RemovesGateOverride()
+ {
+ string command = "1.0 | SET_OVERRIDE | MAIN_GATE | FALSE | 12:00:00";
+
+ ParseTCPCommandResult result = (ParseTCPCommandResult)PrivListener.Invoke("ParseRLString", command);
+ ExecuteTCPCommandResult mvmtResult = (ExecuteTCPCommandResult)PrivListener.Invoke("ExecuteRLCommand", new object[] { result.parsedString });
+
+ Assert.AreEqual(result.parseTCPCommandResultEnum, ParseTCPCommandResultEnum.Success);
+ Assert.AreEqual(mvmtResult.movementResult, MovementResult.Success);
+ Assert.IsFalse(RtController.overrides.overrideGate);
+ }
+
+ [TestMethod]
+ public void TestProcessMessage_SetOverrideSetWeather_SetsWeatherOverride()
+ {
+ string command = "1.0 | SET_OVERRIDE | WEATHER_STATION | TRUE | 12:00:00";
+
+ ParseTCPCommandResult result = (ParseTCPCommandResult)PrivListener.Invoke("ParseRLString", command);
+ ExecuteTCPCommandResult mvmtResult = (ExecuteTCPCommandResult)PrivListener.Invoke("ExecuteRLCommand", new object[] { result.parsedString });
+
+ Assert.AreEqual(result.parseTCPCommandResultEnum, ParseTCPCommandResultEnum.Success);
+ Assert.AreEqual(mvmtResult.movementResult, MovementResult.Success);
+ Assert.IsTrue(ControlRoom.weatherStationOverride);
+ }
+
+ [TestMethod]
+ public void TestProcessMessage_SetOverrideRemWeather_RemovesWeatherOverride()
+ {
+ string command = "1.0 | SET_OVERRIDE | WEATHER_STATION | FALSE | 12:00:00";
+
+ ParseTCPCommandResult result = (ParseTCPCommandResult)PrivListener.Invoke("ParseRLString", command);
+ ExecuteTCPCommandResult mvmtResult = (ExecuteTCPCommandResult)PrivListener.Invoke("ExecuteRLCommand", new object[] { result.parsedString });
+
+ Assert.AreEqual(result.parseTCPCommandResultEnum, ParseTCPCommandResultEnum.Success);
+ Assert.AreEqual(mvmtResult.movementResult, MovementResult.Success);
+ Assert.IsFalse(ControlRoom.weatherStationOverride);
+ }
+
+ [TestMethod]
+ public void TestProcessMessage_SetOverrideInvalidOverride_Fail()
+ {
+ string command = "SET_OVERRIDE CACTUS";
+
+ ParseTCPCommandResult result = (ParseTCPCommandResult)PrivListener.Invoke("ParseRLString", command);
+
+ Assert.AreEqual(result.parseTCPCommandResultEnum, ParseTCPCommandResultEnum.MissingCommandArgs);
+ }
+
+ [TestMethod]
+ public void TestProcessMessage_TestInvalidNumberArgs_SensorOverrideCommand_MissingTimestamp()
+ {
+ string command = "1.0 | SET_OVERRIDE | MAIN_GATE | TRUE ";
+
+ ParseTCPCommandResult result = (ParseTCPCommandResult)PrivListener.Invoke("ParseRLString", command);
+ Assert.AreEqual(ParseTCPCommandResultEnum.MissingCommandArgs, result.parseTCPCommandResultEnum);
+ Assert.IsTrue(result.errorMessage.Contains(TCPCommunicationConstants.MISSING_COMMAND_ARGS));
+ }
+
+ [TestMethod]
+ public void TestProcessMessage_Sensor_Override_InvalidSensor()
+ {
+ string command = "1.0 | SET_OVERRIDE | I_AINT_NO_SENSOR | TRUE | 12:00:00 ";
+
+ ParseTCPCommandResult result = (ParseTCPCommandResult)PrivListener.Invoke("ParseRLString", command);
+ Assert.AreEqual(ParseTCPCommandResultEnum.InvalidCommandArgs, result.parseTCPCommandResultEnum);
+ Assert.IsTrue(result.errorMessage.Contains(TCPCommunicationConstants.INVALID_SENSOR_OVERRIDE));
+ }
+
+ [TestMethod]
+ public void TestProcessMessage_Sensor_Override_InvalidOverride()
+ {
+ string command = "1.0 | SET_OVERRIDE | I_AINT_NO_SENSOR | NOT_T_OR_F| 12:00:00 ";
+
+ ParseTCPCommandResult result = (ParseTCPCommandResult)PrivListener.Invoke("ParseRLString", command);
+ Assert.AreEqual(ParseTCPCommandResultEnum.MissingCommandArgs, result.parseTCPCommandResultEnum);
+ Assert.IsTrue(result.errorMessage.Contains(TCPCommunicationConstants.MISSING_SET_OVERRIDE_ARG));
+ }
+
+ [TestMethod]
+ public void TestProcessMessage_Sensor_Override_MissingOverride()
+ {
+ string command = "1.0 | SET_OVERRIDE | I_AINT_NO_SENSOR | | 12:00:00 ";
+
+ ParseTCPCommandResult result = (ParseTCPCommandResult)PrivListener.Invoke("ParseRLString", command);
+ Assert.AreEqual(ParseTCPCommandResultEnum.MissingCommandArgs, result.parseTCPCommandResultEnum);
+ Assert.IsTrue(result.errorMessage.Contains(TCPCommunicationConstants.MISSING_SET_OVERRIDE_ARG));
+ }
+
+ [TestMethod]
+ public void TestProcessMessage_Sensor_Override_MissingSensor()
+ {
+ string command = "1.0 | SET_OVERRIDE | | TRUE | 12:00:00 ";
+
+ ParseTCPCommandResult result = (ParseTCPCommandResult)PrivListener.Invoke("ParseRLString", command);
+ Assert.AreEqual(ParseTCPCommandResultEnum.InvalidCommandArgs, result.parseTCPCommandResultEnum);
+ Assert.IsTrue(result.errorMessage.Contains(TCPCommunicationConstants.INVALID_SENSOR_OVERRIDE));
+ }
+
+ [TestMethod]
+ public void TestProcessMessage_TestInvalidVersion_DoesNotExist()
+ {
+ string command = "12.0 | STOP_RT | 12:00:00";
+
+ ParseTCPCommandResult result = (ParseTCPCommandResult)PrivListener.Invoke("ParseRLString", command);
+ Assert.AreEqual(ParseTCPCommandResultEnum.InvalidVersion, result.parseTCPCommandResultEnum);
+ Assert.IsTrue(result.errorMessage.Contains(TCPCommunicationConstants.VERSION_NOT_FOUND));
+ }
+
+ [TestMethod]
+ public void TestProcessMessage_TestInvalidVersion_InvalidConversion()
+ {
+ string command = "yoooooo | STOP_RT | 12:00:00";
+
+ ParseTCPCommandResult result = (ParseTCPCommandResult)PrivListener.Invoke("ParseRLString", command);
+ Assert.AreEqual(ParseTCPCommandResultEnum.InvalidVersion, result.parseTCPCommandResultEnum);
+ Assert.IsTrue(result.errorMessage.Contains(TCPCommunicationConstants.VERSION_CONVERSION_ERR));
+ }
+
+
+ [TestMethod]
+ public void TestProcessMessage_TestMissingAzElArgs()
+ {
+ string command = "1.0 | ORIENTATION_MOVE | AZ | EL | 12:00:00";
+ ParseTCPCommandResult result = (ParseTCPCommandResult)PrivListener.Invoke("ParseRLString", command);
+ Assert.AreEqual(result.parseTCPCommandResultEnum, ParseTCPCommandResultEnum.MissingCommandArgs);
+ }
+
+ [TestMethod]
+ public void TestProcessMessage_TestInvalidAzElArgs_ElOutOfRange()
+ {
+ string command = "1.0 | ORIENTATION_MOVE | AZ 50 | EL 500 | 12:00:00";
+ ParseTCPCommandResult result = (ParseTCPCommandResult)PrivListener.Invoke("ParseRLString", command);
+ ExecuteTCPCommandResult mvmtResult = (ExecuteTCPCommandResult)PrivListener.Invoke("ExecuteRLCommand", new object[] { result.parsedString });
+
+ Assert.AreEqual(result.parseTCPCommandResultEnum, ParseTCPCommandResultEnum.Success);
+ Assert.AreEqual(mvmtResult.movementResult, MovementResult.ValidationError);
+ }
+
+ [TestMethod]
+ public void TestProcessMessage_TestInvalidAzElArgs_NotNumbers()
+ {
+ string command = "1.0 | ORIENTATION_MOVE | AZ hi | EL sup | 12:00:00";
+ ParseTCPCommandResult result = (ParseTCPCommandResult)PrivListener.Invoke("ParseRLString", command);
+
+ Assert.AreEqual(result.parseTCPCommandResultEnum, ParseTCPCommandResultEnum.InvalidCommandArgs);
+ Assert.IsTrue(result.errorMessage.Contains(TCPCommunicationConstants.AZ_EL_CONVERSION_ERR));
+ }
+
+ [TestMethod]
+ public void TestProcessMessage_TestInvalidNumberArgs_StopCommand_MissingTimestamp()
+ {
+ string command = "1.0 | STOP_RT ";
+
+ ParseTCPCommandResult result = (ParseTCPCommandResult)PrivListener.Invoke("ParseRLString", command);
+ Assert.AreEqual(ParseTCPCommandResultEnum.MissingCommandArgs, result.parseTCPCommandResultEnum);
+ Assert.IsTrue(result.errorMessage.Contains(TCPCommunicationConstants.MISSING_COMMAND_ARGS));
+ }
+
+ [TestMethod]
+ public void TestProcessMessage_TestInvalidNumberArgs_ScriptCommand_MissingTimestamp()
+ {
+ string command = "1.0 | SCRIPT | DUMP ";
+
+ ParseTCPCommandResult result = (ParseTCPCommandResult)PrivListener.Invoke("ParseRLString", command);
+ Assert.AreEqual(ParseTCPCommandResultEnum.MissingCommandArgs, result.parseTCPCommandResultEnum);
+ Assert.IsTrue(result.errorMessage.Contains(TCPCommunicationConstants.MISSING_COMMAND_ARGS));
+ }
+
+ [TestMethod]
+ public void TestProcessMessage_TestInvalidNumberArgs_AbsMove_MissingTimestamp()
+ {
+ string command = "1.0 | ORIENTATION_MOVE | AZ 20 | EL 40";
+
+ ParseTCPCommandResult result = (ParseTCPCommandResult)PrivListener.Invoke("ParseRLString", command);
+ Assert.AreEqual(ParseTCPCommandResultEnum.MissingCommandArgs, result.parseTCPCommandResultEnum);
+ Assert.IsTrue(result.errorMessage.Contains(TCPCommunicationConstants.MISSING_COMMAND_ARGS));
+ }
+
+ [TestMethod]
+ public void TestProcessMessage_TestInvalidNumberArgs_RelMove_MissingTimestamp()
+ {
+ string command = "1.0 | RELATIVE_MOVE | AZ 20 | EL 40";
+
+ ParseTCPCommandResult result = (ParseTCPCommandResult)PrivListener.Invoke("ParseRLString", command);
+ Assert.AreEqual(ParseTCPCommandResultEnum.MissingCommandArgs, result.parseTCPCommandResultEnum);
+ Assert.IsTrue(result.errorMessage.Contains(TCPCommunicationConstants.MISSING_COMMAND_ARGS));
+ }
+
+ [TestMethod]
+ public void TestProcessMessage_TestInvalidNumberArgs_SensorInit_MissingTimestamp()
+ {
+ string command = "1.0 | SENSOR_INIT | 1,0,1,1,1,1,1,1,1 ";
+
+ ParseTCPCommandResult result = (ParseTCPCommandResult)PrivListener.Invoke("ParseRLString", command);
+ Assert.AreEqual(ParseTCPCommandResultEnum.MissingCommandArgs, result.parseTCPCommandResultEnum);
+ Assert.IsTrue(result.errorMessage.Contains(TCPCommunicationConstants.MISSING_COMMAND_ARGS));
+ }
+
+ [TestMethod]
+ public void TestProcessMessage_TestInvalidNumberArgs_Request_MissingTimestamp()
+ {
+ string command = "1.0 | REQUEST | MVMT_DATA ";
+
+ ParseTCPCommandResult result = (ParseTCPCommandResult)PrivListener.Invoke("ParseRLString", command);
+ Assert.AreEqual(ParseTCPCommandResultEnum.MissingCommandArgs, result.parseTCPCommandResultEnum);
+ Assert.IsTrue(result.errorMessage.Contains(TCPCommunicationConstants.MISSING_COMMAND_ARGS));
+ }
+
+ [TestMethod]
+ public void TestProcessMessage_TestInvalidNumberArgs_Request_InvalidRequest()
+ {
+ string command = "1.0 | REQUEST | NOT_A_REAL_REQUEST | 12:00:00 ";
+
+ ParseTCPCommandResult result = (ParseTCPCommandResult)PrivListener.Invoke("ParseRLString", command);
+ Assert.AreEqual(ParseTCPCommandResultEnum.InvalidRequestType, result.parseTCPCommandResultEnum);
+ Assert.IsTrue(result.errorMessage.Contains(TCPCommunicationConstants.INVALID_REQUEST_TYPE));
+ }
+
+ [TestMethod]
+ public void TestProcessMessage_TestInvalidNumberArgs_MissingVersion()
+ {
+ string command = "REQUEST | MVMT_DATA | 12:00:00";
+
+ ParseTCPCommandResult result = (ParseTCPCommandResult)PrivListener.Invoke("ParseRLString", command);
+ Assert.AreEqual(ParseTCPCommandResultEnum.InvalidVersion, result.parseTCPCommandResultEnum);
+ Assert.IsTrue(result.errorMessage.Contains(TCPCommunicationConstants.VERSION_CONVERSION_ERR));
+ }
+
+ [TestMethod]
+ public void TestProcessMessage_TestInvalidNumberArgs_MissingCommand()
+ {
+ string command = "1.0 | MVMT_DATA | 12:00:00";
+
+ ParseTCPCommandResult result = (ParseTCPCommandResult)PrivListener.Invoke("ParseRLString", command);
+ Assert.AreEqual(ParseTCPCommandResultEnum.InvalidCommandType, result.parseTCPCommandResultEnum);
+ Assert.IsTrue(result.errorMessage.Contains(TCPCommunicationConstants.COMMAND_NOT_FOUND));
+ }
+
+ [TestMethod]
+ public void TestProcessMessage_TestInvalidCommandType()
+ {
+ string command = "1.0 | I_AINT_NO_COMMAND | 12:00:00";
+
+ ParseTCPCommandResult result = (ParseTCPCommandResult)PrivListener.Invoke("ParseRLString", command);
+ Assert.AreEqual(ParseTCPCommandResultEnum.InvalidCommandType, result.parseTCPCommandResultEnum);
+ Assert.IsTrue(result.errorMessage.Contains(TCPCommunicationConstants.COMMAND_NOT_FOUND));
+ }
+
+ [TestMethod]
+ public void TestProcessMessage_TestInvalidScriptType()
+ {
+ string command = "1.0 | SCRIPT | I_AINT_NO_SCRIPT | 12:00:00";
+
+ ParseTCPCommandResult result = (ParseTCPCommandResult)PrivListener.Invoke("ParseRLString", command);
+ Assert.AreEqual(ParseTCPCommandResultEnum.InvalidScript, result.parseTCPCommandResultEnum);
+ Assert.IsTrue(result.errorMessage.Contains(TCPCommunicationConstants.SCRIPT_NOT_FOUND));
+ }
+
+ // Test happy paths
+ [TestMethod]
+ public void TestProcessMessage_TestValidOrientationMove()
+ {
+ string command = "1.0 | ORIENTATION_MOVE | AZ 10 | EL 30 | 12:00:00";
+
+ ParseTCPCommandResult result = (ParseTCPCommandResult)PrivListener.Invoke("ParseRLString", command);
+ Assert.AreEqual(ParseTCPCommandResultEnum.Success, result.parseTCPCommandResultEnum);
+ }
+
+ [TestMethod]
+ public void TestProcessMessage_TestValidRelativeMove()
+ {
+ string command = "1.0 | RELATIVE_MOVE | AZ 1 | EL 1 | 12:00:00";
+
+ ParseTCPCommandResult result = (ParseTCPCommandResult)PrivListener.Invoke("ParseRLString", command);
+ Assert.AreEqual(ParseTCPCommandResultEnum.Success, result.parseTCPCommandResultEnum);
+ }
+
+ [TestMethod]
+ public void TestProcessMessage_TestValidScript()
+ {
+ string command = "1.0 | SCRIPT | DUMP | 12:00:00";
+
+ ParseTCPCommandResult result = (ParseTCPCommandResult)PrivListener.Invoke("ParseRLString", command);
+ Assert.AreEqual(ParseTCPCommandResultEnum.Success, result.parseTCPCommandResultEnum);
+ }
+
+ [TestMethod]
+ public void TestProcessMessage_TestValidRequest()
+ {
+ string command = "1.0 | REQUEST | MVMT_DATA | 12:00:00";
+
+ ParseTCPCommandResult result = (ParseTCPCommandResult)PrivListener.Invoke("ParseRLString", command);
+ Assert.AreEqual(ParseTCPCommandResultEnum.Success, result.parseTCPCommandResultEnum);
+ }
+
+ [TestMethod]
+ public void TestProcessMessage_TestValidStopRT()
+ {
+ string command = "1.0 | STOP_RT | 12:00:00";
+
+ ParseTCPCommandResult result = (ParseTCPCommandResult)PrivListener.Invoke("ParseRLString", command);
+ ExecuteTCPCommandResult mvmtResult = (ExecuteTCPCommandResult)PrivListener.Invoke("ExecuteRLCommand", new object[] { result.parsedString });
+ Assert.AreEqual(ParseTCPCommandResultEnum.Success, result.parseTCPCommandResultEnum);
+ Assert.AreEqual(MovementResult.Success, mvmtResult.movementResult);
+ }
+
+ [TestMethod]
+ public void TestProcessMessage_TestEncryptedMessage()
+ {
+ string receivedCommand = "1.1|AA9uv3O7ov+eZ2xM9478QpgOxSBhBbyYMf21krHQMZLAdnaAqGwJ2GkZcT8hxE7T";
+
+ Tuple dataPair = Utilities.CheckEncrypted(receivedCommand);
+
+ string command = dataPair.Item1;
+
+ ParseTCPCommandResult result = (ParseTCPCommandResult)PrivListener.Invoke("ParseRLString", command);
+ Assert.AreEqual(ParseTCPCommandResultEnum.Success, result.parseTCPCommandResultEnum);
+ }
+
+ [TestMethod]
+ public void TestProcessMessage_TestEncryptionUnsupportedVersion()
+ {
+ string receivedCommand = "1.0 | STOP_RT | 12:00:00";
+
+ Tuple dataPair = Utilities.CheckEncrypted(receivedCommand);
+
+ Assert.IsTrue(receivedCommand.Equals(dataPair.Item1));
+ Assert.IsFalse(dataPair.Item2);
+ }
+
+ [TestMethod]
+ public void TestProcessMessage_TestValidResetMCUErrorBit()
+ {
+ string command = "1.1 | RESET_MCU_BIT | 12:00:00";
+
+ ParseTCPCommandResult result = (ParseTCPCommandResult)PrivListener.Invoke("ParseRLString", command);
+ ExecuteTCPCommandResult resetResult = (ExecuteTCPCommandResult)PrivListener.Invoke("ExecuteRLCommand", new object[] { result.parsedString });
+ Assert.AreEqual(ParseTCPCommandResultEnum.Success, result.parseTCPCommandResultEnum);
+ Assert.AreEqual(MCUResetResult.Success, resetResult.resetResult);
+ }
+
+ [TestMethod]
+ public void TestProcessMessage_TestResetMCUErrorBit_MissingTimestamp()
+ {
+ string command = "1.1 | RESET_MCU_BIT";
+
+ ParseTCPCommandResult result = (ParseTCPCommandResult)PrivListener.Invoke("ParseRLString", command);
+ ExecuteTCPCommandResult resetResult = (ExecuteTCPCommandResult)PrivListener.Invoke("ExecuteRLCommand", new object[] { result.parsedString });
+ Assert.AreEqual(ParseTCPCommandResultEnum.MissingCommandArgs, result.parseTCPCommandResultEnum);
+ }
+
+ [TestMethod]
+ public void TestProcessMessage_TestResetMCUErrorBit_UnsupportedVersion()
+ {
+ string command = "1.0 | RESET_MCU_BIT | 12:00:00";
+
+ ParseTCPCommandResult result = (ParseTCPCommandResult)PrivListener.Invoke("ParseRLString", command);
+ ExecuteTCPCommandResult resetResult = (ExecuteTCPCommandResult)PrivListener.Invoke("ExecuteRLCommand", new object[] { result.parsedString });
+ Assert.AreEqual(ParseTCPCommandResultEnum.InvalidVersion, result.parseTCPCommandResultEnum);
+ }
+
+ [TestMethod]
+ public void TestProcessMessage_TestRequestMCU()
+ {
+ string command = "1.1 | REQUEST | MVMT_DATA | 12:00:00 ";
+
+ ParseTCPCommandResult result = (ParseTCPCommandResult)PrivListener.Invoke("ParseRLString", command);
+ ExecuteTCPCommandResult resetResult = (ExecuteTCPCommandResult)PrivListener.Invoke("ExecuteRLCommand", new object[] { result.parsedString });
+ Assert.AreEqual(ParseTCPCommandResultEnum.Success, result.parseTCPCommandResultEnum);
+ }
+
+ [TestMethod]
+ public void TestProcessMessage_TestNewTCPVersion()
+ {
+ string command = "1.1 | STOP_RT | 12:00:00"; // Run a command from an older version of TCP with a new version
+
+ ParseTCPCommandResult result = (ParseTCPCommandResult)PrivListener.Invoke("ParseRLString", command);
+ ExecuteTCPCommandResult mvmtResult = (ExecuteTCPCommandResult)PrivListener.Invoke("ExecuteRLCommand", new object[] { result.parsedString });
+ Assert.AreEqual(ParseTCPCommandResultEnum.Success, result.parseTCPCommandResultEnum);
+ Assert.AreEqual(MovementResult.Success, mvmtResult.movementResult);
+ }
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/ControlRoomApplicationTest.csproj b/ControlRoomApplication/ControlRoomApplicationTest/ControlRoomApplicationTest.csproj
index 776e2983..5b07b345 100644
--- a/ControlRoomApplication/ControlRoomApplicationTest/ControlRoomApplicationTest.csproj
+++ b/ControlRoomApplication/ControlRoomApplicationTest/ControlRoomApplicationTest.csproj
@@ -47,10 +47,13 @@
..\packages\AASharp.1.99.1\lib\net45\AASharp.dll
- ..\packages\AWSSDK.Core.3.3.103.16\lib\net45\AWSSDK.Core.dll
+ ..\packages\AWSSDK.Core.3.5.1.26\lib\net45\AWSSDK.Core.dll
- ..\packages\AWSSDK.RDS.3.3.107.9\lib\net45\AWSSDK.RDS.dll
+ ..\packages\AWSSDK.RDS.3.5.0\lib\net45\AWSSDK.RDS.dll
+
+
+ ..\packages\AWSSDK.SimpleEmail.3.5.0.28\lib\net45\AWSSDK.SimpleEmail.dll
..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.dll
@@ -58,6 +61,9 @@
..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.SqlServer.dll
+
+ ..\packages\FftSharp.1.0.8\lib\netstandard2.0\FftSharp.dll
+
..\packages\MSTest.TestFramework.1.4.0\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll
@@ -70,17 +76,37 @@
..\packages\NModbus4.2.1.0\lib\net40\NModbus4.dll
+
+ ..\packages\ScottPlot.4.0.48\lib\netstandard2.0\ScottPlot.dll
+
+
+ ..\packages\ScottPlot.WinForms.4.0.48\lib\net461\ScottPlot.WinForms.dll
+
+
+
+ ..\packages\System.Drawing.Common.4.7.0\lib\net461\System.Drawing.Common.dll
+
+
..\packages\System.ValueTuple.4.5.0\lib\net461\System.ValueTuple.dll
+
+
+
+
+
+
-
+
+
+
+
@@ -92,27 +118,56 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Designer
@@ -124,7 +179,8 @@
-
+
+
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/DatabaseOperationsTests/DatabaseOperationsTests.cs b/ControlRoomApplication/ControlRoomApplicationTest/DatabaseOperationsTests/DatabaseOperationsTests.cs
index c4d08d30..89ab0dcc 100644
--- a/ControlRoomApplication/ControlRoomApplicationTest/DatabaseOperationsTests/DatabaseOperationsTests.cs
+++ b/ControlRoomApplication/ControlRoomApplicationTest/DatabaseOperationsTests/DatabaseOperationsTests.cs
@@ -1,9 +1,13 @@
using System;
using System.Linq;
+using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using ControlRoomApplication.Constants;
using ControlRoomApplication.Database;
using ControlRoomApplication.Entities;
+using ControlRoomApplication.Controllers;
+using System.Threading;
+using System.Text;
namespace ControlRoomApplicationTest.DatabaseOperationsTests
{
@@ -14,180 +18,692 @@ public class DatabaseOperationsTests
private RFData data1;
private RFData data2;
private RFData data3;
+ private RFData data4;
// Test Appointment objects
private Appointment appt;
private int NumRTInstances = 1;
+ private int NumAppointments = 0;
+ private int NumRFData = -1;
[TestInitialize]
public void BuildUp()
{
- // Initialize context
- DatabaseOperations.PopulateLocalDatabase(NumRTInstances);
+ NumAppointments = DatabaseOperations.GetTotalAppointmentCount();
+ NumRTInstances = DatabaseOperations.GetTotalRTCount();
+ NumRFData = DatabaseOperations.GetTotalRFDataCount();
+
+ appt = new Appointment();
+ appt.start_time = DateTime.UtcNow;
+ appt.end_time = DateTime.UtcNow.AddMinutes(1);
+ appt._Status = AppointmentStatusEnum.IN_PROGRESS;
+ appt._Priority = AppointmentPriorityEnum.MANUAL;
+ appt._Type = AppointmentTypeEnum.FREE_CONTROL;
+ appt.Coordinates.Add(new Coordinate(0, 0));
+ appt.CelestialBody = new CelestialBody();
+ appt.CelestialBody.Coordinate = new Coordinate();
+ appt.Orientation = new Orientation();
+ appt.SpectraCyberConfig = new SpectraCyberConfig(SpectraCyberModeTypeEnum.CONTINUUM);
+ appt.Telescope = new RadioTelescope(new SpectraCyberController(new SpectraCyber()), new TestPLCDriver(PLCConstants.LOCAL_HOST_IP, PLCConstants.LOCAL_HOST_IP, 8089, 8089, false), new Location(), new Orientation());
+ appt.Telescope._TeleType = RadioTelescopeTypeEnum.SLIP_RING;
+ appt.User = DatabaseOperations.GetControlRoomUser();
+
+ DatabaseOperations.AddRadioTelescope(appt.Telescope);
+ DatabaseOperations.AddAppointment(appt);
// RFData initialization
data1 = new RFData();
data2 = new RFData();
data3 = new RFData();
- DateTime date = DateTime.UtcNow;
+ data4 = new RFData();
+ DateTime now = DateTime.UtcNow;
+ DateTime date = new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute, now.Second);
+ Appointment RFappt = appt;
data1.Intensity = 9234875;
data1.TimeCaptured = date;
+ data1.Appointment = RFappt;
data2.Intensity = 8739425;
- data2.TimeCaptured = date.AddSeconds(5);
+ data2.TimeCaptured = date.AddSeconds(3);
+ data2.Appointment = RFappt;
data3.Intensity = 12987;
- data3.TimeCaptured = date.AddSeconds(10);
+ data3.TimeCaptured = date.AddSeconds(4);
+ data3.Appointment = RFappt;
- // Init appt
- appt = DatabaseOperations.GetListOfAppointmentsForRadioTelescope(NumRTInstances)[0];
+ data4.Intensity = 12987;
+ data4.TimeCaptured = date.AddSeconds(5);
+ data4.Appointment = RFappt;
- }
-
- [TestCleanup]
- public void TearDown()
- {
- DatabaseOperations.DeleteLocalDatabase();
- }
+ NumAppointments++;
+ NumRTInstances++;
- [TestMethod]
- public void TestPopulateLocalDatabase()
- {
- DatabaseOperations.DeleteLocalDatabase();
- DatabaseOperations.PopulateLocalDatabase(NumRTInstances);
- var appt_count = DatabaseOperations.GetTotalAppointmentCount();
- Assert.AreEqual(4 * NumRTInstances, appt_count);
- }
-
- [TestMethod]
- public void TestDeleteLocalDatabase()
- {
- DatabaseOperations.DeleteLocalDatabase();
- var appt_count = DatabaseOperations.GetTotalAppointmentCount();
- Assert.AreEqual(0, appt_count);
- DatabaseOperations.PopulateLocalDatabase(NumRTInstances);
}
[TestMethod]
public void TestGetListOfAppointmentsForRadioTelescope()
{
- var appts = DatabaseOperations.GetListOfAppointmentsForRadioTelescope(NumRTInstances);
- Assert.AreEqual(4 * NumRTInstances, appts.Count);
+ var appts = DatabaseOperations.GetListOfAppointmentsForRadioTelescope(appt.Telescope.Id);
+ Assert.AreEqual(1, appts.Count);
}
[TestMethod]
public void TestAddAppointment()
{
var new_appt = new Appointment();
- new_appt.StartTime = DateTime.UtcNow;
- new_appt.EndTime = DateTime.UtcNow.AddMinutes(1);
- new_appt.Status = AppointmentStatusEnum.REQUESTED;
- new_appt.Type = AppointmentTypeEnum.POINT;
- new_appt.Coordinates.Add(new Coordinate(0,0));
+ new_appt.start_time = DateTime.UtcNow;
+ new_appt.end_time = DateTime.UtcNow.AddMinutes(1);
+ new_appt._Status = AppointmentStatusEnum.REQUESTED;
+ new_appt._Priority = AppointmentPriorityEnum.MANUAL;
+ new_appt._Type = AppointmentTypeEnum.POINT;
+ new_appt.Coordinates.Add(new Coordinate(15, 15));
+ new_appt.CelestialBody = new CelestialBody();
+ new_appt.CelestialBody.Coordinate = new Coordinate();
+ new_appt.Orientation = new Orientation();
new_appt.SpectraCyberConfig = new SpectraCyberConfig(SpectraCyberModeTypeEnum.CONTINUUM);
- new_appt.TelescopeId = 1;
- new_appt.UserId = 1;
+ new_appt.Telescope = appt.Telescope;
+ new_appt.User = DatabaseOperations.GetControlRoomUser();
+
+ //new_appt.Telescope.type = appt.Telescope.type;
+ //DatabaseOperations.AddRadioTelescope(new_appt.Telescope);
DatabaseOperations.AddAppointment(new_appt);
- var output_appts = DatabaseOperations.GetListOfAppointmentsForRadioTelescope(1);
- Assert.IsTrue(1 == output_appts.Where(x => x.Id == new_appt.Id).Count());
+
+ var output_appts = DatabaseOperations.GetListOfAppointmentsForRadioTelescope(new_appt.Telescope.Id);
+
+ Assert.IsTrue(2 == output_appts.Count()); // Should be two appointments retrieved
+
+ //Assert.AreEqual(new_appt.start_time.ToString(), output_appts[0].start_time.ToString());
+ //Assert.AreEqual(new_appt.end_time.ToString(), output_appts[0].end_time.ToString());
+ Assert.AreEqual(new_appt._Status, output_appts[1]._Status);
+ Assert.AreEqual(new_appt._Priority, output_appts[1]._Priority);
+ Assert.AreEqual(new_appt._Type, output_appts[1]._Type);
+
+ // Coordinates
+ Assert.AreEqual(new_appt.Id, output_appts[1].Coordinates.First().apptId);
+ Assert.AreEqual(new_appt.Coordinates.First().hours, output_appts[1].Coordinates.First().hours);
+ Assert.AreEqual(new_appt.Coordinates.First().minutes, output_appts[1].Coordinates.First().minutes);
+ Assert.AreEqual(new_appt.Coordinates.First().Declination, output_appts[1].Coordinates.First().Declination);
+ Assert.AreEqual(new_appt.Coordinates.First().RightAscension, output_appts[1].Coordinates.First().RightAscension);
+
+ // Other entities that Appointment uses
+ Assert.AreEqual(new_appt.celestial_body_id, output_appts[1].celestial_body_id);
+ Assert.AreEqual(new_appt.orientation_id, output_appts[1].orientation_id);
+ Assert.AreEqual(new_appt.spectracyber_config_id, output_appts[1].spectracyber_config_id);
+ Assert.AreEqual(new_appt.telescope_id, output_appts[1].telescope_id);
+ Assert.AreEqual(new_appt.user_id, output_appts[1].user_id);
}
[TestMethod]
public void TestGetTotalAppointmentCount()
{
var appt_count = DatabaseOperations.GetTotalAppointmentCount();
- Assert.AreEqual(4 * NumRTInstances, appt_count);
+ Assert.AreEqual(NumAppointments, appt_count);
}
[TestMethod]
public void TestCreateRFData()
{
- DatabaseOperations.CreateRFData(appt.Id, data1);
- DatabaseOperations.CreateRFData(appt.Id, data2);
- DatabaseOperations.CreateRFData(appt.Id, data3);
+ DatabaseOperations.AddRFData(data1);
+ DatabaseOperations.AddRFData(data2);
- // update appt
- appt = DatabaseOperations.GetListOfAppointmentsForRadioTelescope(NumRTInstances).Find(x => x.Id == appt.Id);
+ Assert.AreEqual(DatabaseOperations.GetTotalRFDataCount(), NumRFData + 2);
+
+ List datas = DatabaseOperations.GetListOfRFData();
+ RFData dbData1 = datas.Find(x => x.Id == data1.Id);
+ RFData dbData2 = datas.Find(x => x.Id == data2.Id);
+
+ Assert.IsTrue(dbData1 != null);
+ Assert.IsTrue(dbData2 != null);
- Assert.AreEqual(appt.RFDatas.ToList().Find(x => x.Id == data1.Id).Intensity, data1.Intensity);
- Assert.AreEqual(appt.RFDatas.ToList().Find(x => x.Id == data2.Id).Intensity, data2.Intensity);
- Assert.AreEqual(appt.RFDatas.ToList().Find(x => x.Id == data3.Id).Intensity, data3.Intensity);
+ Assert.AreEqual(dbData1.Intensity, data1.Intensity);
+ Assert.AreEqual(dbData2.Intensity, data2.Intensity);
+
+ Assert.IsTrue(dbData1.TimeCaptured == data1.TimeCaptured);
+ Assert.IsTrue(dbData2.TimeCaptured == data2.TimeCaptured);
- Assert.AreEqual(appt.RFDatas.ToList().Find(x => x.Id == data1.Id).TimeCaptured.Date, data1.TimeCaptured.Date);
- Assert.AreEqual(appt.RFDatas.ToList().Find(x => x.Id == data2.Id).TimeCaptured.Date, data2.TimeCaptured.Date);
- Assert.AreEqual(appt.RFDatas.ToList().Find(x => x.Id == data3.Id).TimeCaptured.Date, data3.TimeCaptured.Date);
}
[TestMethod]
public void TestCreateRFData_InvalidDate()
{
- data1.TimeCaptured = DateTime.UtcNow.AddDays(1);
+ data3.TimeCaptured = DateTime.UtcNow.AddDays(1);
- DatabaseOperations.CreateRFData(appt.Id, data1);
+ DatabaseOperations.AddRFData(data3);
- // update appt
- appt = DatabaseOperations.GetListOfAppointmentsForRadioTelescope(NumRTInstances).Find(x => x.Id == appt.Id);
+ List datas = DatabaseOperations.GetListOfRFData();
- RFData testData = appt.RFDatas.ToList().Find(x => x.Id == data1.Id);
+ RFData testData = appt.RFDatas.ToList().Find(x => x.Id == data3.Id);
- Assert.AreEqual(null, testData);
+ Assert.AreEqual(null, datas.Find(t => t.Id == data3.Id));
}
[TestMethod]
public void TestCreateRFData_InvalidIntensity()
{
- data1.Intensity = -239458;
+ data4.Intensity = -239458;
- DatabaseOperations.CreateRFData(appt.Id, data1);
+ DatabaseOperations.AddRFData(data4);
- // update appt
- appt = DatabaseOperations.GetListOfAppointmentsForRadioTelescope(NumRTInstances).Find(x => x.Id == appt.Id);
+ List datas = DatabaseOperations.GetListOfRFData();
- RFData testData = appt.RFDatas.ToList().Find(x => x.Id == data1.Id);
+ RFData testData = appt.RFDatas.ToList().Find(x => x.Id == data4.Id);
- Assert.AreEqual(null, testData);
+ Assert.AreEqual(null, datas.Find(t => t.Id == data4.Id));
}
[TestMethod]
public void TestUpdateAppointmentStatus()
{
- appt.Status = AppointmentStatusEnum.IN_PROGRESS;
+ appt._Status = AppointmentStatusEnum.IN_PROGRESS;
DatabaseOperations.UpdateAppointment(appt);
-
+
// update appt
- appt = DatabaseOperations.GetListOfAppointmentsForRadioTelescope(NumRTInstances).Find(x => x.Id == appt.Id);
- var testStatus = appt.Status;
+ appt = DatabaseOperations.GetListOfAppointmentsForRadioTelescope(appt.Telescope.Id).Find(x => x.Id == appt.Id);
+ var testStatus = appt._Status;
Assert.AreEqual(AppointmentStatusEnum.IN_PROGRESS, testStatus);
}
[TestMethod]
- public void TestUpdateAppointmentCoordinates()
+ public void TestUpdateAppointmentPriority()
{
- var origCoord = new Coordinate(0, 0);
- appt.Coordinates.Add(origCoord);
+ var expectedPriority = AppointmentPriorityEnum.MANUAL;
+ appt._Priority = expectedPriority;
DatabaseOperations.UpdateAppointment(appt);
// update appt
- appt = DatabaseOperations.GetListOfAppointmentsForRadioTelescope(NumRTInstances).Find(x => x.Id == appt.Id);
+ appt = DatabaseOperations.GetListOfAppointmentsForRadioTelescope(appt.Telescope.Id).Find(x => x.Id == appt.Id);
- var testCoord = appt.Coordinates.First();
+ var resultPriority = appt._Priority;
- Assert.AreEqual(origCoord.RightAscension, testCoord.RightAscension);
- Assert.AreEqual(origCoord.Declination, testCoord.Declination);
+ Assert.AreEqual(expectedPriority, resultPriority);
+ }
+
+ [TestMethod]
+ public void TestUpdateAppointmentCoordinates()
+ {
+ // Create expected coordinates and add to the appointment
+ var coords = new Coordinate(5, 5);
+ appt.Coordinates.Add(coords);
+
+ // Add appointment to the database
+ DatabaseOperations.UpdateAppointment(appt);
+
+ // Retrieve appointment from the database
+ appt = DatabaseOperations.GetListOfAppointmentsForRadioTelescope(appt.Telescope.Id).Find(x => x.Id == appt.Id);
+ List resultCoordinates = appt.Coordinates.ToList();
+
+ // Verify only two results are returned
+ Assert.IsTrue(resultCoordinates.Count == 2);
+
+ // Create expected coordinate list
+ List expectedCoordinates = new List();
+ expectedCoordinates.Add(new Coordinate(0, 0));
+ expectedCoordinates.Add(new Coordinate(5, 5));
+
+ // Verify coordinates are correct
+ Assert.AreEqual(expectedCoordinates[0].Declination, resultCoordinates[0].Declination);
+ Assert.AreEqual(expectedCoordinates[0].RightAscension, resultCoordinates[0].RightAscension);
+
+ Assert.AreEqual(expectedCoordinates[1].Declination, resultCoordinates[1].Declination);
+ Assert.AreEqual(expectedCoordinates[1].RightAscension, resultCoordinates[1].RightAscension);
+
+ }
+
+ [TestMethod]
+ public void TestAddThenDeleteCoordinates()
+ {
+ // Create expected coordinates and add to the appointment
+ var coords = new Coordinate(5, 5);
+ appt.Coordinates.Add(coords);
+
+ // Add appointment to the database
+ DatabaseOperations.UpdateAppointment(appt);
+
+ Thread.Sleep(100);
+
+ // Delete coordinates and then update the DB entry
+ appt.Coordinates.Remove(coords);
+ DatabaseOperations.UpdateAppointment(appt);
+
+ // Retrieve appointment from the database
+ appt = DatabaseOperations.GetListOfAppointmentsForRadioTelescope(appt.Telescope.Id).Find(x => x.Id == appt.Id);
+ List resultCoordinates = appt.Coordinates.ToList();
+
+ // Verify only one result is returned
+ Assert.IsTrue(resultCoordinates.Count == 1);
+
+ // Create expected coordinate
+ Coordinate expectedCoordinate = new Coordinate(0, 0);
+
+ // Verify coordinates are correct
+ Assert.AreEqual(expectedCoordinate.Declination, resultCoordinates[0].Declination);
+ Assert.AreEqual(expectedCoordinate.RightAscension, resultCoordinates[0].RightAscension);
}
[TestMethod]
public void TestGetNextAppointment()
{
- var appt = DatabaseOperations.GetNextAppointment(NumRTInstances);
- Assert.IsTrue(appt != null);
- Assert.IsTrue(appt.StartTime > DateTime.UtcNow);
- Assert.IsTrue(appt.Status != AppointmentStatusEnum.COMPLETED);
+ var nextAppt = DatabaseOperations.GetNextAppointment(appt.Telescope.Id);
+ Assert.IsTrue(nextAppt != null);
+ Assert.IsTrue(nextAppt._Status != AppointmentStatusEnum.COMPLETED);
+ }
+
+ [TestMethod]
+ public void TestSetOverrideForSensor()
+ {
+ bool before = DatabaseOperations.GetOverrideStatusForSensor(SensorItemEnum.GATE);
+
+ DatabaseOperations.SetOverrideForSensor(SensorItemEnum.GATE, !before);
+
+ bool after = DatabaseOperations.GetOverrideStatusForSensor(SensorItemEnum.GATE);
+
+ Assert.IsTrue(before != after);
+ }
+
+ [TestMethod]
+ public void TestGetThresholdForSensor()
+ {
+ double wind = DatabaseOperations.GetThresholdForSensor(SensorItemEnum.WIND);
+ Assert.IsTrue(wind > 0);
+
+ double az_motor_temp = DatabaseOperations.GetThresholdForSensor(SensorItemEnum.AZ_MOTOR_TEMP);
+ Assert.IsTrue(az_motor_temp > 0);
+
+ double elev_motor_temp = DatabaseOperations.GetThresholdForSensor(SensorItemEnum.ELEV_MOTOR_TEMP);
+ Assert.IsTrue(elev_motor_temp > 0);
+
+ double az_motor_vibe = DatabaseOperations.GetThresholdForSensor(SensorItemEnum.AZ_MOTOR_VIBRATION);
+ Assert.IsTrue(az_motor_vibe > 0);
+
+ double elev_motor_vibe = DatabaseOperations.GetThresholdForSensor(SensorItemEnum.ELEV_MOTOR_VIBRATION);
+ Assert.IsTrue(elev_motor_vibe > 0);
+
+ double az_motor_current = DatabaseOperations.GetThresholdForSensor(SensorItemEnum.AZ_MOTOR_CURRENT);
+ Assert.IsTrue(az_motor_current > 0);
+
+ double elev_motor_current = DatabaseOperations.GetThresholdForSensor(SensorItemEnum.ELEV_MOTOR_CURRENT);
+ Assert.IsTrue(elev_motor_current > 0);
+
+ double counter_vibe = DatabaseOperations.GetThresholdForSensor(SensorItemEnum.COUNTER_BALANCE_VIBRATION);
+ Assert.IsTrue(counter_vibe > 0);
+ }
+
+ [TestMethod]
+ public void TestGetAllUsers()
+ {
+ List users = new List();
+ users = DatabaseOperations.GetAllUsers();
+ Assert.IsTrue(users.Count > 0);
+ }
+
+ [TestMethod]
+ public void TestGetAllAdminUsers()
+ {
+ List AdminUsers = new List();
+
+ AdminUsers = DatabaseOperations.GetAllAdminUsers(true);
+ Assert.IsTrue(AdminUsers.Count > 0);
+ Assert.IsTrue(AdminUsers.All(user => user.UR._User_Role == UserRoleEnum.ADMIN));
+ }
+
+ [TestMethod]
+ public void TestAddAndRetrieveRadioTelescope()
+ {
+ RadioTelescope telescope = new RadioTelescope();
+
+ // not saved in the database
+ telescope.SpectraCyberController = new SpectraCyberController(new SpectraCyber());
+ telescope.PLCDriver = new TestPLCDriver(PLCConstants.LOCAL_HOST_IP, PLCConstants.LOCAL_HOST_IP, 8089, 8089, false);
+
+ // saved in the database
+ telescope.online = 1;
+ telescope.CurrentOrientation = new Orientation(25, 25);
+ telescope.CalibrationOrientation = new Orientation(30, 30);
+ telescope.Location = new Location(1, 2, 3, "test");
+ telescope._TeleType = RadioTelescopeTypeEnum.SLIP_RING;
+ telescope.maxElevationDegrees = MiscellaneousConstants.MAX_SOFTWARE_STOP_EL_DEGREES;
+ telescope.minElevationDegrees = MiscellaneousConstants.MIN_SOFTWARE_STOP_EL_DEGREES;
+
+ DatabaseOperations.AddRadioTelescope(telescope);
+
+ RadioTelescope retrievedTele = DatabaseOperations.FetchLastRadioTelescope();
+ RadioTelescope teleByID = DatabaseOperations.FetchRadioTelescopeByID(retrievedTele.Id);
+
+
+ // online
+ Assert.IsTrue(telescope.online == retrievedTele.online);
+
+ // type
+ Assert.IsTrue(telescope.teleType == retrievedTele.teleType);
+
+ // location
+ Assert.IsTrue(telescope.Location.Latitude == retrievedTele.Location.Latitude);
+ Assert.IsTrue(telescope.Location.Longitude == retrievedTele.Location.Longitude);
+ Assert.IsTrue(telescope.Location.Altitude == retrievedTele.Location.Altitude);
+ Assert.IsTrue(telescope.Location.Name == retrievedTele.Location.Name);
+
+ // current orientation (not yet implemented)
+ Assert.IsTrue(telescope.CurrentOrientation.Azimuth == retrievedTele.CurrentOrientation.Azimuth);
+ Assert.IsTrue(telescope.CurrentOrientation.Elevation == retrievedTele.CurrentOrientation.Elevation);
+
+ // calibration orientation (not yet implemented)
+ Assert.IsTrue(telescope.CalibrationOrientation.Azimuth == retrievedTele.CalibrationOrientation.Azimuth);
+ Assert.IsTrue(telescope.CalibrationOrientation.Elevation == retrievedTele.CalibrationOrientation.Elevation);
+
+ // elevation thresholds
+ Assert.IsTrue(telescope.maxElevationDegrees == retrievedTele.maxElevationDegrees);
+ Assert.IsTrue(telescope.minElevationDegrees == retrievedTele.minElevationDegrees);
+
+ // test FetchByID
+ // we will never have this many telescopes, just ensuring null operation performed correctly
+ Assert.IsTrue(DatabaseOperations.FetchRadioTelescopeByID(32323232) == null);
+
+ Assert.IsFalse(teleByID == null);
+ Assert.IsFalse(teleByID.Location == null);
+ Assert.IsFalse(teleByID.CalibrationOrientation == null);
+ Assert.IsFalse(teleByID.CurrentOrientation == null);
+ Assert.IsTrue(teleByID.Id == retrievedTele.Id);
+ Assert.IsTrue(teleByID.Location.Latitude == retrievedTele.Location.Latitude);
+ Assert.IsTrue(teleByID.Location.Longitude == retrievedTele.Location.Longitude);
+ Assert.IsTrue(teleByID.Location.Altitude == retrievedTele.Location.Altitude);
+ Assert.IsTrue(teleByID.Location.Name == retrievedTele.Location.Name);
+ Assert.IsTrue(teleByID.CurrentOrientation.Azimuth == retrievedTele.CurrentOrientation.Azimuth);
+ Assert.IsTrue(teleByID.CurrentOrientation.Elevation == retrievedTele.CurrentOrientation.Elevation);
+ Assert.IsTrue(teleByID.CalibrationOrientation.Azimuth == retrievedTele.CalibrationOrientation.Azimuth);
+ Assert.IsTrue(teleByID.CalibrationOrientation.Elevation == retrievedTele.CalibrationOrientation.Elevation);
+ Assert.IsTrue(teleByID.maxElevationDegrees == retrievedTele.maxElevationDegrees);
+ Assert.IsTrue(teleByID.minElevationDegrees == retrievedTele.minElevationDegrees);
+ }
+
+ [TestMethod]
+ public void TestAddAndRetrieveTemperature()
+ {
+ Temperature[] temp = new Temperature[1];
+ SensorLocationEnum loc1 = SensorLocationEnum.AZ_MOTOR;
+
+ //Generate current time
+ long dateTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
+
+ //Generate Temperature
+ Temperature t1 = Temperature.Generate(dateTime, 0.0, loc1);
+
+ temp[0] = (t1);
+
+ DatabaseOperations.AddSensorData(temp, true);
+ List tempReturn = DatabaseOperations.GetTEMPData(dateTime - 1, dateTime + 1, loc1);
+
+ Assert.AreEqual(tempReturn.Count, 1);
+
+ //Test only temp
+ Assert.AreEqual(temp[tempReturn.Count - 1].location_ID, tempReturn[tempReturn.Count - 1].location_ID);
+ Assert.AreEqual(temp[tempReturn.Count - 1].temp, tempReturn[tempReturn.Count - 1].temp);
+ Assert.AreEqual(temp[tempReturn.Count - 1].TimeCapturedUTC, tempReturn[tempReturn.Count - 1].TimeCapturedUTC);
+
+ }
+
+ [TestMethod]
+ public void TestAddAndRetrieveTemperatures()
+ {
+ Temperature[] temp = new Temperature[2];
+ SensorLocationEnum loc1 = SensorLocationEnum.AZ_MOTOR;
+
+ //Generate current time
+ long dateTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
+
+ //Make 2 new temperatures
+ Temperature t1 = Temperature.Generate(dateTime, 500.0, loc1);
+ Temperature t2 = Temperature.Generate(dateTime, 999.0, loc1);
+
+ temp[0] = (t1);
+ temp[1] = (t2);
+
+ DatabaseOperations.AddSensorData(temp, true);
+ List tempReturn = DatabaseOperations.GetTEMPData(dateTime - 1, dateTime + 1, loc1);
+
+ Assert.AreEqual(tempReturn.Count, 2);
+
+ //Test first temp
+ Assert.AreEqual(temp[tempReturn.Count - 1].location_ID, tempReturn[tempReturn.Count - 1].location_ID);
+ Assert.AreEqual(temp[tempReturn.Count - 1].temp, tempReturn[tempReturn.Count - 1].temp);
+ Assert.AreEqual(temp[tempReturn.Count - 1].TimeCapturedUTC, tempReturn[tempReturn.Count - 1].TimeCapturedUTC);
+
+ //Test second temp
+ Assert.AreEqual(temp[tempReturn.Count - 2].location_ID, tempReturn[tempReturn.Count - 2].location_ID);
+ Assert.AreEqual(temp[tempReturn.Count - 2].temp, tempReturn[tempReturn.Count - 2].temp);
+ Assert.AreEqual(temp[tempReturn.Count - 2].TimeCapturedUTC, tempReturn[tempReturn.Count - 2].TimeCapturedUTC);
+
+ }
+
+ //Acceleration
+ [TestMethod]
+ public void TestAddAndRetrieveAcceleration()
+ {
+ Acceleration[] acc = new Acceleration[1];
+ SensorLocationEnum loc1 = SensorLocationEnum.AZ_MOTOR;
+
+ //Generate current time
+ long dateTime1 = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
+
+ //Generate Acceleration
+ Acceleration a1 = Acceleration.Generate(dateTime1, 1, 1, 1, loc1);
+
+ acc[0] = a1;
+
+ DatabaseOperations.AddSensorData(acc, true);
+ List accReturn = DatabaseOperations.GetACCData(dateTime1 - 1, dateTime1 + 1, loc1);
+
+ Assert.AreEqual(accReturn.Count, 1);
+
+ //Test only acc
+ Assert.AreEqual(acc[accReturn.Count - 1].location_ID, accReturn[accReturn.Count - 1].location_ID);
+ Assert.AreEqual(acc[accReturn.Count - 1].x, accReturn[accReturn.Count - 1].x);
+ Assert.AreEqual(acc[accReturn.Count - 1].y, accReturn[accReturn.Count - 1].y);
+ Assert.AreEqual(acc[accReturn.Count - 1].z, accReturn[accReturn.Count - 1].z);
+ Assert.AreEqual(acc[accReturn.Count - 1].TimeCaptured, accReturn[accReturn.Count - 1].TimeCaptured);
+
+ }
+
+ [TestMethod]
+ public void TestAddAndRetrieveAccelerations()
+ {
+ Acceleration[] acc = new Acceleration[2];
+ SensorLocationEnum loc1 = SensorLocationEnum.AZ_MOTOR;
+
+ //Generate current time
+ long dateTime1 = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
+
+ //Make 2 new Accelerations
+ Acceleration a1 = Acceleration.Generate(dateTime1, 1, 1, 1, loc1);
+ Acceleration a2 = Acceleration.Generate(dateTime1, 2, 2, 2, loc1);
+
+ acc[0] = (a1);
+ acc[1] = (a2);
+
+
+ DatabaseOperations.AddSensorData(acc, true);
+ List accReturn = DatabaseOperations.GetACCData(dateTime1 - 1, dateTime1 + 1, loc1);
+
+ Assert.AreEqual(accReturn.Count, 2);
+
+ //Test first acc
+ Assert.AreEqual(acc[accReturn.Count - 1].location_ID, accReturn[accReturn.Count - 1].location_ID);
+ Assert.AreEqual(acc[accReturn.Count - 1].x, accReturn[accReturn.Count - 1].x);
+ Assert.AreEqual(acc[accReturn.Count - 1].y, accReturn[accReturn.Count - 1].y);
+ Assert.AreEqual(acc[accReturn.Count - 1].z, accReturn[accReturn.Count - 1].z);
+ Assert.AreEqual(acc[accReturn.Count - 1].TimeCaptured, accReturn[accReturn.Count - 1].TimeCaptured);
+
+ //Test second acc
+ Assert.AreEqual(acc[accReturn.Count - 2].location_ID, accReturn[accReturn.Count - 2].location_ID);
+ Assert.AreEqual(acc[accReturn.Count - 2].x, accReturn[accReturn.Count - 2].x);
+ Assert.AreEqual(acc[accReturn.Count - 2].y, accReturn[accReturn.Count - 2].y);
+ Assert.AreEqual(acc[accReturn.Count - 2].z, accReturn[accReturn.Count - 2].z);
+ Assert.AreEqual(acc[accReturn.Count - 2].TimeCaptured, accReturn[accReturn.Count - 2].TimeCaptured);
+
+ }
+
+ [TestMethod]
+ public void TestUpdateTelescope()
+ {
+ RadioTelescope telescope = new RadioTelescope();
+
+ // saved in the database
+ telescope.online = 0;
+ telescope.CurrentOrientation = new Orientation(0, 0);
+ telescope.CalibrationOrientation = new Orientation(0, 0);
+ telescope.Location = new Location(0, 0, 0, "");
+ telescope._TeleType = RadioTelescopeTypeEnum.NONE;
+ telescope.maxElevationDegrees = MiscellaneousConstants.MAX_SOFTWARE_STOP_EL_DEGREES;
+ telescope.minElevationDegrees = MiscellaneousConstants.MIN_SOFTWARE_STOP_EL_DEGREES;
+ DatabaseOperations.AddRadioTelescope(telescope);
+ RadioTelescope retrievedTele = DatabaseOperations.FetchLastRadioTelescope();
+
+
+ // not saved in the database
+ telescope.SpectraCyberController = new SpectraCyberController(new SpectraCyber());
+ telescope.PLCDriver = new TestPLCDriver(PLCConstants.LOCAL_HOST_IP, PLCConstants.LOCAL_HOST_IP, 8089, 8089, false);
+
+ // saved in the database
+ telescope.Id = retrievedTele.Id;
+ telescope.online = 1;
+ telescope.CurrentOrientation = new Orientation(25, 25);
+ telescope.CalibrationOrientation = new Orientation(30, 30);
+ telescope.Location = new Location(1, 2, 3, "test");
+ telescope._TeleType = RadioTelescopeTypeEnum.SLIP_RING;
+ telescope.maxElevationDegrees = 90;
+ telescope.minElevationDegrees = 0;
+
+ DatabaseOperations.UpdateTelescope(telescope);
+
+ retrievedTele = DatabaseOperations.FetchLastRadioTelescope();
+
+ // online
+ Assert.IsTrue(telescope.online == retrievedTele.online);
+
+ // type
+ Assert.IsTrue(telescope.teleType == retrievedTele.teleType);
+
+ // location
+ Assert.IsTrue(telescope.Location.Latitude == retrievedTele.Location.Latitude);
+ Assert.IsTrue(telescope.Location.Longitude == retrievedTele.Location.Longitude);
+ Assert.IsTrue(telescope.Location.Altitude == retrievedTele.Location.Altitude);
+ Assert.IsTrue(telescope.Location.Name == retrievedTele.Location.Name);
+
+ // current orientation (not yet implemented)
+ Assert.IsTrue(telescope.CurrentOrientation.Azimuth == retrievedTele.CurrentOrientation.Azimuth);
+ Assert.IsTrue(telescope.CurrentOrientation.Elevation == retrievedTele.CurrentOrientation.Elevation);
+
+ // calibration orientation (not yet implemented)
+ Assert.IsTrue(telescope.CalibrationOrientation.Azimuth == retrievedTele.CalibrationOrientation.Azimuth);
+ Assert.IsTrue(telescope.CalibrationOrientation.Elevation == retrievedTele.CalibrationOrientation.Elevation);
+
+ // elevation thresholds
+ Assert.IsTrue(telescope.maxElevationDegrees == retrievedTele.maxElevationDegrees);
+ Assert.IsTrue(telescope.minElevationDegrees == retrievedTele.minElevationDegrees);
+ }
+
+ [TestMethod]
+ public void TestAddAndRetrieveSensorNetworkConfig_Valid_CreatesConfig()
+ {
+ int telescopeId = 5;
+
+ // Create new SensorNetworkConfig with a telescope ID of 5
+ SensorNetworkConfig original = new SensorNetworkConfig(telescopeId);
+
+ original.TimeoutDataRetrieval = 5;
+ original.TimeoutInitialization = 5;
+
+ DatabaseOperations.AddSensorNetworkConfig(original);
+
+ var retrieved = DatabaseOperations.RetrieveSensorNetworkConfigByTelescopeId(telescopeId);
+
+ Assert.IsTrue(original.Equals(retrieved));
+
+ // Delete config
+ DatabaseOperations.DeleteSensorNetworkConfig(original);
+ }
+
+ [TestMethod]
+ public void TestUpdateSensorNetworkConfig_ChangeAllFields_UpdatesConfig()
+ {
+ int telescopeId = 5;
+ SensorNetworkConfig original = new SensorNetworkConfig(telescopeId);
+
+ // Save original config
+ DatabaseOperations.AddSensorNetworkConfig(original);
+
+ // Change values so the updated one is different
+ original.ElevationTemp1Init = false;
+ original.AzimuthTemp1Init = false;
+ original.ElevationAccelerometerInit = false;
+ original.AzimuthAccelerometerInit = false;
+ original.CounterbalanceAccelerometerInit = false;
+ original.ElevationEncoderInit = false;
+ original.AzimuthEncoderInit = false;
+ original.TimeoutDataRetrieval = 5;
+ original.TimeoutInitialization = 5;
+
+ // Update config
+ DatabaseOperations.UpdateSensorNetworkConfig(original);
+
+ var retrieved = DatabaseOperations.RetrieveSensorNetworkConfigByTelescopeId(telescopeId);
+
+ Assert.IsTrue(original.Equals(retrieved));
+
+ // Delete config
+ DatabaseOperations.DeleteSensorNetworkConfig(original);
+ }
+
+ [TestMethod]
+ public void TestUpdateSensorNetworkConfig_TelescopeDoesntExist_ShouldThrowInvalidOperationException()
+ {
+ SensorNetworkConfig invalidConfig = new SensorNetworkConfig(9000);
+
+ Assert.ThrowsException(() =>
+ DatabaseOperations.UpdateSensorNetworkConfig(invalidConfig)
+ );
+ }
+
+ [TestMethod]
+ public void TestDeleteSensorNetworkConfig_ConfigExists_DeletesConfig()
+ {
+ int telescopeId = 10;
+ SensorNetworkConfig config = new SensorNetworkConfig(telescopeId);
+
+ // Save config
+ DatabaseOperations.AddSensorNetworkConfig(config);
+
+ // Delete config
+ DatabaseOperations.DeleteSensorNetworkConfig(config);
+
+ // Attempt to find config
+ SensorNetworkConfig result = DatabaseOperations.RetrieveSensorNetworkConfigByTelescopeId(telescopeId);
+
+ Assert.IsTrue(result == null);
+ }
+
+ [TestMethod]
+ public void TestDeleteSensorNetworkConfig_TelescopeDoesntExist_ShouldThrowInvalidOperationException()
+ {
+ SensorNetworkConfig invalidConfig = new SensorNetworkConfig(9000);
+
+ Assert.ThrowsException(() =>
+ DatabaseOperations.DeleteSensorNetworkConfig(invalidConfig)
+ );
+ }
+
+ [TestMethod]
+ public void testAddAndFetchWeatherStation()
+ {
+ WeatherThreshold testThreshold = new WeatherThreshold(10, 120);
+ DatabaseOperations.AddWeatherThreshold(testThreshold);
+ int time = DatabaseOperations.FetchWeatherThreshold().SnowDumpTime;
+ Assert.AreEqual(120, time);
+
}
}
}
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/DatabaseOperationsTests/RTDbContextTests.cs b/ControlRoomApplication/ControlRoomApplicationTest/DatabaseOperationsTests/RTDbContextTests.cs
index d85a5914..41400566 100644
--- a/ControlRoomApplication/ControlRoomApplicationTest/DatabaseOperationsTests/RTDbContextTests.cs
+++ b/ControlRoomApplication/ControlRoomApplicationTest/DatabaseOperationsTests/RTDbContextTests.cs
@@ -8,13 +8,11 @@ namespace ControlRoomApplicationTest.DatabaseOperationsTests
public class RTDbContextTests
{
private RTDbContext context1;
- private RTDbContext context2;
[TestInitialize]
public void BuildUp()
{
- context1 = new RTDbContext();
- context2 = new RTDbContext("server=localhost;uid=root;persistsecurityinfo=True;database=RTDatabase;allowuservariables=True");
+ context1 = new RTDbContext("server=localhost;database=radio_telescope;uid=root;pwd=ycpRT2018!;");
}
[TestMethod]
@@ -27,9 +25,6 @@ public void TestContextInitialization()
Assert.AreEqual(MiscellaneousConstants.LOCAL_DATABASE_NAME.ToLower(), context1.Database.Connection.Database.ToLower());
Assert.AreEqual("localhost", context1.Database.Connection.DataSource);
-
- Assert.AreEqual(MiscellaneousConstants.LOCAL_DATABASE_NAME.ToLower(), context2.Database.Connection.Database.ToLower());
- Assert.IsFalse(context2.Configuration.LazyLoadingEnabled);
}
}
}
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/EntitiesTests/AccelerationBlobTest.cs b/ControlRoomApplication/ControlRoomApplicationTest/EntitiesTests/AccelerationBlobTest.cs
new file mode 100644
index 00000000..da192fe0
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplicationTest/EntitiesTests/AccelerationBlobTest.cs
@@ -0,0 +1,172 @@
+using ControlRoomApplication.Database;
+using ControlRoomApplication.Entities;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System;
+using System.Collections.Generic;
+
+namespace ControlRoomApplicationTest.EntitiesTests
+{
+ [TestClass]
+ public class AccelerationBlobTest
+ {
+ // Class being tested
+ Acceleration azAcc, cbAcc, elAcc;
+ Acceleration[] azAccArr, cbAccArr, elAccArr;
+ AzimuthAccelerationBlob azBlob;
+ CounterbalanceAccelerationBlob cbBlob;
+ ElevationAccelerationBlob elBlob;
+ List blobData;
+
+ [TestInitialize]
+ public void BuildUp()
+ {
+
+ //byte array to store 32 acceleration data points
+ blobData = new List();
+ azBlob = new AzimuthAccelerationBlob();
+ cbBlob = new CounterbalanceAccelerationBlob();
+ elBlob = new ElevationAccelerationBlob();
+ azAcc = Acceleration.Generate(DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(), 1, 2, 3, SensorLocationEnum.AZ_MOTOR);
+ cbAcc = Acceleration.Generate(DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(), 1, 2, 3, SensorLocationEnum.COUNTERBALANCE);
+ elAcc = Acceleration.Generate(DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(), 1, 2, 3, SensorLocationEnum.EL_MOTOR);
+
+ //version
+ blobData.Add(1);
+
+ //FIFO Size
+ blobData.Add(32);
+
+ //SampleFrequency
+ byte[] frequency = BitConverter.GetBytes(800);
+ blobData.Add(frequency[0]);
+ blobData.Add(frequency[1]);
+
+ //GRange
+ blobData.Add(1);
+
+ //full resolution
+ blobData.Add(BitConverter.GetBytes(true)[0]);
+
+ //label
+ char label = 't';
+ blobData.Add(BitConverter.GetBytes(label)[0]);
+
+
+ //time
+ byte[] time = BitConverter.GetBytes(azAcc.TimeCaptured);
+
+ for (int i = 0; i < 8; i++)
+ {
+ blobData.Add(time[i]);
+ }
+
+ //acc x
+ byte[] accX = BitConverter.GetBytes(azAcc.x);
+
+ for (int i = 0; i < 2; i++)
+ {
+ blobData.Add(accX[i]);
+ }
+ //acc x
+ byte[] accY = BitConverter.GetBytes(azAcc.y);
+
+ for (int i = 0; i < 2; i++)
+ {
+ blobData.Add(accY[i]);
+ }
+
+ //acc z
+ byte[] accZ = BitConverter.GetBytes(azAcc.z);
+ for(int i=0; i<2; i++)
+ {
+ blobData.Add(accZ[i]);
+ }
+
+
+ // write 31 data points without time
+ for(int size=0; size < 31; size++)
+ {
+ //label
+ label = 'a';
+ blobData.Add(BitConverter.GetBytes(label)[0]);
+
+ //acc x
+ for (int i = 0; i < 2; i++)
+ {
+ blobData.Add(accX[i]);
+ }
+ //acc y
+ for (int i = 0; i < 2; i++)
+ {
+ blobData.Add(accY[i]);
+ }
+
+ //acc z
+ for (int i = 0; i < 2; i++)
+ {
+ blobData.Add(accZ[i]);
+ }
+ }
+
+ //save the three blobs
+
+ azBlob.BlobList = blobData;
+ cbBlob.BlobList = blobData;
+ elBlob.BlobList = blobData;
+
+
+ // create the three comparison acceleration arrays
+ azAccArr = new Acceleration[32];
+ cbAccArr = new Acceleration[32];
+ elAccArr = new Acceleration[32];
+
+ for (int i=0; i<32; i++)
+ {
+ azAccArr[i] = azAcc;
+ cbAccArr[i] = cbAcc;
+ elAccArr[i] = elAcc;
+ }
+
+ }
+
+ [TestMethod]
+ public void TestParsing()
+ {
+ //Check the first acceleration datapoint
+ Assert.IsTrue(azAcc.Equals(azBlob.BlobParser(azBlob.BlobList.ToArray())[0]));
+ Assert.IsTrue(cbAcc.Equals(cbBlob.BlobParser(cbBlob.BlobList.ToArray())[0]));
+ Assert.IsTrue(elAcc.Equals(elBlob.BlobParser(elBlob.BlobList.ToArray())[0]));
+
+ //check the acceleration array
+ Assert.IsTrue(Acceleration.SequenceEquals(azAccArr, azBlob.BlobParser(azBlob.BlobList.ToArray())));
+ Assert.IsTrue(Acceleration.SequenceEquals(cbAccArr, cbBlob.BlobParser(cbBlob.BlobList.ToArray())));
+ Assert.IsTrue(Acceleration.SequenceEquals(elAccArr, elBlob.BlobParser(elBlob.BlobList.ToArray())));
+
+ //print out the blob
+ Console.WriteLine(azBlob.blobToString(azBlob.BlobList.ToArray()));
+
+ }
+
+ [TestMethod]
+ public void TestBlobbing()
+ {
+ //run the dependent test
+ TestParsing();
+
+ //blobs and then parses and checks that the parsed values are correct
+ //if the parse is incorrect, then the blobber is incorrect, since the Parsing function test passes, as it is a dependent test
+
+ azBlob.BuildAccelerationBlob(azAccArr, 1,32, 800, 16,true, true);
+ Assert.IsTrue(Acceleration.SequenceEquals(azBlob.BlobParser(azBlob.BlobArray), azAccArr));
+
+ cbBlob.BuildAccelerationBlob(cbAccArr, 1, 32, 800, 16, true, true);
+ Assert.IsTrue(Acceleration.SequenceEquals(cbBlob.BlobParser(cbBlob.BlobArray), cbAccArr));
+
+ elBlob.BuildAccelerationBlob(elAccArr, 1, 32, 800, 16, true, true);
+ Assert.IsTrue(Acceleration.SequenceEquals(elBlob.BlobParser(elBlob.BlobArray), elAccArr));
+
+
+ }
+ }
+}
+
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/EntitiesTests/AccelerationTest.cs b/ControlRoomApplication/ControlRoomApplicationTest/EntitiesTests/AccelerationTest.cs
new file mode 100644
index 00000000..b39585ca
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplicationTest/EntitiesTests/AccelerationTest.cs
@@ -0,0 +1,187 @@
+using ControlRoomApplication.Entities;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System;
+using System.Collections.Generic;
+
+namespace ControlRoomApplicationTest.EntitiesTests
+{
+ [TestClass]
+ public class AccelerationTest
+ {
+ // Class being tested
+ private Acceleration Acceleration;
+
+ [TestInitialize]
+ public void BuildUp()
+ {
+
+ }
+
+ [TestMethod]
+ public void TestGettersAndSetters()
+ {
+ // Initialize appointment entity
+ SensorLocationEnum loc1 = SensorLocationEnum.AZ_MOTOR;
+
+ //Generate current time
+ long dateTime1 = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
+ long dateTime2 = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
+
+ //Generate Acceleration
+ Acceleration a1 = Acceleration.Generate(dateTime1, 0, 0, 0, loc1);
+ //Acceleration t2 = Acceleration.Generate(dateTime, 2.0, loc1);
+
+
+ a1.TimeCaptured = dateTime2;
+ Assert.AreEqual(a1.TimeCaptured, dateTime2);
+ a1.x = 1;
+ Assert.AreEqual(a1.x, 1);
+ a1.y = 1;
+ Assert.AreEqual(a1.y, 1);
+ a1.z = 1;
+ Assert.AreEqual(a1.z, 1);
+ a1.location_ID = 1;
+ Assert.AreEqual(a1.location_ID, 1);
+
+ }
+
+ [TestMethod]
+ public void TestGenerate()
+ {
+ // Initialize appointment entity
+ SensorLocationEnum loc1 = SensorLocationEnum.AZ_MOTOR;
+
+ //Generate current time
+ long dateTime1 = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
+
+ //Generate Acceleration
+ Acceleration a1 = Acceleration.Generate(dateTime1, 1, 1, 1, loc1);
+
+ Assert.AreEqual(a1.TimeCaptured, dateTime1);
+ Assert.AreEqual(a1.x, 1);
+ Assert.AreEqual(a1.y, 1);
+ Assert.AreEqual(a1.z, 1);
+ Assert.AreEqual(a1.location_ID, (int)loc1);
+
+ }
+
+ [TestMethod]
+ public void TestAddAndRetrieveAcceleration()
+ {
+ List acc = new List();
+ SensorLocationEnum loc1 = SensorLocationEnum.AZ_MOTOR;
+
+ //Generate current time
+ long dateTime1 = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
+
+ //Generate Acceleration
+ Acceleration a1 = Acceleration.Generate(dateTime1, 1, 1, 1, loc1);
+
+ acc.Add(a1);
+
+
+ //Test acc
+ Assert.AreEqual(acc[0].TimeCaptured, dateTime1);
+ Assert.AreEqual(acc[0].x, 1);
+ Assert.AreEqual(acc[0].y, 1);
+ Assert.AreEqual(acc[0].z, 1);
+ Assert.AreEqual(acc[0].location_ID, (int)loc1);
+ }
+
+ [TestMethod]
+ public void TestAddAndRetrieveAccelerations()
+ {
+ List acc = new List();
+ SensorLocationEnum loc1 = SensorLocationEnum.AZ_MOTOR;
+ SensorLocationEnum loc2 = SensorLocationEnum.EL_MOTOR;
+
+ //Generate current time
+ long dateTime1 = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
+ long dateTime2 = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
+
+
+ //Generate Acceleration
+ Acceleration a1 = Acceleration.Generate(dateTime1, 1, 1, 1, loc1);
+ Acceleration a2 = Acceleration.Generate(dateTime2, 2, 2, 2, loc2);
+
+
+ acc.Add(a1);
+ acc.Add(a2);
+
+ //Test acc
+ Assert.AreEqual(acc[0].TimeCaptured, dateTime1);
+ Assert.AreEqual(acc[0].x, 1);
+ Assert.AreEqual(acc[0].y, 1);
+ Assert.AreEqual(acc[0].z, 1);
+ Assert.AreEqual(acc[0].location_ID, (int)loc1);
+
+ Assert.AreEqual(acc[1].TimeCaptured, dateTime2);
+ Assert.AreEqual(acc[1].x, 2);
+ Assert.AreEqual(acc[1].y, 2);
+ Assert.AreEqual(acc[1].z, 2);
+ Assert.AreEqual(acc[1].location_ID, (int)loc2);
+
+ }
+
+ [TestMethod]
+ public void TestEquals()
+ {
+ SensorLocationEnum loc1 = SensorLocationEnum.AZ_MOTOR;
+ SensorLocationEnum loc2 = SensorLocationEnum.EL_MOTOR;
+
+ //Generate current time
+ long dateTime1 = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
+ long dateTime2 = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
+
+
+ //Generate Temperature
+ Acceleration a1 = Acceleration.Generate(dateTime1, 1, 1, 1, loc1);
+ Acceleration a2 = Acceleration.Generate(dateTime2, 2, 2, 2, loc2);
+
+
+ Assert.AreEqual(a1, a1);
+ Assert.AreNotEqual(a1, a2);
+ Assert.AreNotEqual(a2, a1);
+ }
+
+ [TestMethod]
+ public void TestSequenceEquals()
+ {
+ SensorLocationEnum loc1 = SensorLocationEnum.AZ_MOTOR;
+ SensorLocationEnum loc2 = SensorLocationEnum.EL_MOTOR;
+
+ Acceleration[] acc1 = new Acceleration[2];
+ Acceleration[] acc2= new Acceleration[2];
+ Acceleration[] acc3 = new Acceleration[2];
+ Acceleration[] acc4 = new Acceleration[1];
+
+
+ //Generate current time
+ long dateTime1 = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
+ long dateTime2 = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
+
+
+ //Generate Temperature
+ Acceleration a1 = Acceleration.Generate(dateTime1, 1, 1, 1, loc1);
+ Acceleration a2 = Acceleration.Generate(dateTime2, 2, 2, 2, loc2);
+ Acceleration a3 = Acceleration.Generate(dateTime2, 3, 3, 3, loc2);
+
+ acc1[0] = a1;
+ acc1[1] = a2;
+
+ acc2[0] = a1;
+ acc2[1] = a2;
+
+ acc3[0] = a2;
+ acc3[1] = a3;
+
+ acc4[0] = a1;
+
+ Assert.IsTrue(Acceleration.SequenceEquals(acc1, acc2));
+ Assert.IsFalse(Acceleration.SequenceEquals(acc2, acc3));
+ Assert.IsFalse(Acceleration.SequenceEquals(acc1, acc4));
+
+ }
+ }
+}
+
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/EntitiesTests/AppointmentTest.cs b/ControlRoomApplication/ControlRoomApplicationTest/EntitiesTests/AppointmentTest.cs
index 524052fa..11e6b6f8 100644
--- a/ControlRoomApplication/ControlRoomApplicationTest/EntitiesTests/AppointmentTest.cs
+++ b/ControlRoomApplication/ControlRoomApplicationTest/EntitiesTests/AppointmentTest.cs
@@ -1,5 +1,6 @@
using ControlRoomApplication.Constants;
using ControlRoomApplication.Entities;
+using ControlRoomApplication.Controllers;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Linq;
@@ -11,19 +12,21 @@ public class AppointmentTest
{
// Class being tested
private Appointment appointment_1;
- private Appointment appointment_2;
+ private Appointment greaterThan;
+ private Appointment equalTo;
// Attributes in the class that need to be tested
- private int user_id;
+ private User controlRoomUser;
private DateTime startTime_1;
private DateTime endTime_1;
private CelestialBody celestial_body;
private Orientation orientation;
private Coordinate coordinate;
+ private RadioTelescope telescope;
private RFData rf_data;
- private int telescope_id;
private AppointmentStatusEnum status;
private AppointmentTypeEnum type;
+ private SpectraCyber spectraCyber;
private SpectraCyberConfig spectracyber_config;
private DateTime startTime_2;
@@ -35,18 +38,19 @@ public void BuildUp()
{
// Initialize appointment entity
appointment_1 = new Appointment();
- appointment_2 = new Appointment();
+ greaterThan = new Appointment();
// Initialize data for fields
- user_id = 1;
+ controlRoomUser = new User("control", "room", "controlroom@gmail.com", NotificationTypeEnum.SMS);
startTime_1 = DateTime.UtcNow;
endTime_1 = DateTime.UtcNow.AddHours(1);
celestial_body = new CelestialBody(CelestialBodyConstants.SUN);
orientation = new Orientation(20, 20);
coordinate = new Coordinate(20, 20);
+ spectraCyber = new SpectraCyber();
+ telescope = new RadioTelescope(new SpectraCyberController(spectraCyber), new TestPLCDriver(PLCConstants.LOCAL_HOST_IP, PLCConstants.LOCAL_HOST_IP, 8089, 8089, false), new Location(), new Orientation());
rf_data = new RFData();
rf_data.Intensity = 100;
- telescope_id = 1;
status = AppointmentStatusEnum.REQUESTED;
type = AppointmentTypeEnum.POINT;
spectracyber_config = new SpectraCyberConfig(SpectraCyberModeTypeEnum.CONTINUUM);
@@ -55,43 +59,47 @@ public void BuildUp()
endTime_2 = DateTime.UtcNow.AddDays(1).AddHours(1);
// Initialize fields we are testing against
- appointment_1.UserId = user_id;
- appointment_1.StartTime = startTime_1;
- appointment_1.EndTime = endTime_1;
+ appointment_1.User = controlRoomUser;
+ appointment_1.start_time = startTime_1;
+ appointment_1.end_time = endTime_1;
appointment_1.CelestialBody = celestial_body;
appointment_1.Orientation = orientation;
appointment_1.Coordinates.Add(coordinate);
appointment_1.RFDatas.Add(rf_data);
- appointment_1.TelescopeId = telescope_id;
- appointment_1.Status = status;
- appointment_1.Type = type;
+ appointment_1._Status = status;
+ appointment_1._Type = type;
appointment_1.SpectraCyberConfig = spectracyber_config;
+ appointment_1.Telescope = telescope;
- appointment_2.StartTime = startTime_2;
- appointment_2.EndTime = endTime_2;
+ greaterThan.start_time = startTime_2;
+ greaterThan.end_time = endTime_2;
+
+ equalTo = appointment_1;
}
[TestMethod]
public void TestGettersAndSetters()
{
- Assert.AreEqual(user_id, appointment_1.UserId);
- Assert.AreEqual(startTime_1, appointment_1.StartTime);
- Assert.AreEqual(endTime_1, appointment_1.EndTime);
- Assert.AreEqual(celestial_body, appointment_1.CelestialBody);
- Assert.AreEqual(orientation, appointment_1.Orientation);
+ Assert.AreEqual(controlRoomUser.Id, appointment_1.User.Id);
+ Assert.AreEqual(startTime_1, appointment_1.start_time);
+ Assert.AreEqual(endTime_1, appointment_1.end_time);
+ Assert.AreEqual(celestial_body.Id, appointment_1.CelestialBody.Id);
+ Assert.AreEqual(orientation.Id, appointment_1.Orientation.Id);
Assert.AreEqual(coordinate, appointment_1.Coordinates.ToList()[0]);
Assert.AreEqual(rf_data, appointment_1.RFDatas.ToList()[0]);
- Assert.AreEqual(telescope_id, appointment_1.TelescopeId);
- Assert.AreEqual(status, appointment_1.Status);
- Assert.AreEqual(type, appointment_1.Type);
- Assert.AreEqual(spectracyber_config, appointment_1.SpectraCyberConfig);
+ Assert.AreEqual(telescope.Id, appointment_1.Telescope.Id);
+ Assert.AreEqual(status, appointment_1._Status);
+ Assert.AreEqual(type, appointment_1._Type);
+ Assert.AreEqual(spectracyber_config.Id, appointment_1.SpectraCyberConfig.Id);
}
[TestMethod]
public void TestComparable()
{
- Assert.IsTrue(appointment_1 != appointment_2);
- Assert.IsTrue(appointment_1 < appointment_2);
+ Assert.IsTrue(appointment_1 != greaterThan);
+ Assert.IsTrue(appointment_1 < greaterThan);
+ Assert.IsTrue(greaterThan > appointment_1);
+ Assert.IsTrue(appointment_1 == equalTo);
}
}
}
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/EntitiesTests/ControlRoomTest.cs b/ControlRoomApplication/ControlRoomApplicationTest/EntitiesTests/ControlRoomTest.cs
index 18c4b640..63467eb2 100644
--- a/ControlRoomApplication/ControlRoomApplicationTest/EntitiesTests/ControlRoomTest.cs
+++ b/ControlRoomApplication/ControlRoomApplicationTest/EntitiesTests/ControlRoomTest.cs
@@ -3,36 +3,69 @@
using ControlRoomApplication.Entities;
using ControlRoomApplication.Controllers;
using ControlRoomApplication.Constants;
+using System.Net.Sockets;
+using System.Net;
+using ControlRoomApplication.Controllers.SensorNetwork;
namespace ControlRoomApplicationTest.EntitiesTests
{
[TestClass]
public class ControlRoomTest
{
- private ControlRoom controlRoom;
+ private static ControlRoom controlRoom;
private AbstractWeatherStation weatherStation;
private List rtManagementThreads;
+ // PLC driver
+ readonly string PlcIp = "127.0.0.1";
+ readonly int PlcPort = 4000;
+ readonly string McuIp = "127.0.0.1";
+ readonly int McuPort = 4010;
+
+ // Sensor Network
+ readonly IPAddress SnServerIp = IPAddress.Parse("127.0.0.1");
+ readonly int SnServerPort = 3000;
+ readonly string SnClientIp = "127.0.0.1";
+ readonly int SnClientPort = 3001;
+ readonly int SnTelescopeId = 3000;
+
[TestInitialize]
- public void BuildUp()
- {
- string IP = PLCConstants.LOCAL_HOST_IP;
+ public void BuildUp() {
+
+ SensorNetworkServer SN = new SensorNetworkServer(SnServerIp, SnServerPort, SnClientIp, SnClientPort, SnTelescopeId, true);
rtManagementThreads = new List()
{
new RadioTelescopeControllerManagementThread(new RadioTelescopeController(
- new RadioTelescope(new SpectraCyberController(new SpectraCyber()), new SimulationPLCDriver(IP, IP, 8103, 8103), new Location(), new Orientation()))),
+ new RadioTelescope(new SpectraCyberSimulatorController(new SpectraCyberSimulator()), new SimulationPLCDriver(PlcIp, McuIp, McuPort, PlcPort, true, false), new Location(), new Orientation() , 1, SN))),
new RadioTelescopeControllerManagementThread(new RadioTelescopeController(
- new RadioTelescope(new SpectraCyberController(new SpectraCyber()), new SimulationPLCDriver(IP, IP, 8106, 8106), new Location(), new Orientation()))),
+ new RadioTelescope(new SpectraCyberSimulatorController(new SpectraCyberSimulator()), new SimulationPLCDriver(PlcIp, McuIp, McuPort+1, PlcPort+1, true, false), new Location(), new Orientation(), 2, SN))),
new RadioTelescopeControllerManagementThread(new RadioTelescopeController(
- new RadioTelescope(new SpectraCyberController(new SpectraCyber()), new SimulationPLCDriver(IP, IP, 8109, 8109), new Location(), new Orientation()))),
+ new RadioTelescope(new SpectraCyberSimulatorController(new SpectraCyberSimulator()), new SimulationPLCDriver(PlcIp, McuIp, McuPort+2, PlcPort+2, true, false), new Location(), new Orientation() , 3, SN))),
};
- controlRoom = new ControlRoom(weatherStation);
- controlRoom.RTControllerManagementThreads.Add(rtManagementThreads[0]);
- controlRoom.RTControllerManagementThreads.Add(rtManagementThreads[1]);
- controlRoom.RTControllerManagementThreads.Add(rtManagementThreads[2]);
+ controlRoom = new ControlRoom( weatherStation, 87 );
+
+ // End the CR's listener's server. We have to do this until we stop hard-coding that dang value.
+ // TODO: Remove this logic when the value is no longer hard-coded (issue #350)
+ //PrivateObject listener = new PrivateObject(controlRoom.mobileControlServer);
+ //((TcpListener)listener.GetFieldOrProperty("server")).Stop();
+
+ controlRoom.RTControllerManagementThreads.Add( rtManagementThreads[0] );
+ controlRoom.RTControllerManagementThreads.Add( rtManagementThreads[1] );
+ controlRoom.RTControllerManagementThreads.Add( rtManagementThreads[2] );
}
+
+ [ClassCleanup]
+ public static void cleanUp()
+ {
+ foreach (RadioTelescopeControllerManagementThread RTCMT in controlRoom.RTControllerManagementThreads)
+ {
+ RTCMT.RequestToKill();
+ }
+ controlRoom.mobileControlServer.RequestToKillTCPMonitoringRoutine();
+ }
+
[TestMethod]
public void TestGettersAndSetters()
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/EntitiesTests/HeartbeatInterfaceTests/ConcreteHeartbeatTestClass.cs b/ControlRoomApplication/ControlRoomApplicationTest/EntitiesTests/HeartbeatInterfaceTests/ConcreteHeartbeatTestClass.cs
index 14e0b5cf..8447c53e 100644
--- a/ControlRoomApplication/ControlRoomApplicationTest/EntitiesTests/HeartbeatInterfaceTests/ConcreteHeartbeatTestClass.cs
+++ b/ControlRoomApplication/ControlRoomApplicationTest/EntitiesTests/HeartbeatInterfaceTests/ConcreteHeartbeatTestClass.cs
@@ -10,10 +10,11 @@ public ConcreteHeartbeatTestClass()
protected override bool KillHeartbeatComponent()
{
- throw new System.NotImplementedException();
+ // kill imaginary heartbeat
+ return true;
}
- protected override bool TestIfComponentIsAlive()
+ public override bool TestIfComponentIsAlive()
{
throw new System.NotImplementedException();
}
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/EntitiesTests/HeartbeatInterfaceTests/HeartbeatInterfaceTest.cs b/ControlRoomApplication/ControlRoomApplicationTest/EntitiesTests/HeartbeatInterfaceTests/HeartbeatInterfaceTest.cs
index 4467d7b7..cc728f63 100644
--- a/ControlRoomApplication/ControlRoomApplicationTest/EntitiesTests/HeartbeatInterfaceTests/HeartbeatInterfaceTest.cs
+++ b/ControlRoomApplication/ControlRoomApplicationTest/EntitiesTests/HeartbeatInterfaceTests/HeartbeatInterfaceTest.cs
@@ -6,12 +6,16 @@ namespace ControlRoomApplicationTest.EntitiesTests
[TestClass]
public class HeartbeatInterfaceTest
{
- private ConcreteHeartbeatTestClass concreteHeartbeat;
+ private ConcreteHeartbeatTestClass concreteHeartbeat1;
+ private ConcreteHeartbeatTestClass concreteHeartbeat2;
+ private ConcreteHeartbeatTestClass concreteHeartbeat3;
[TestInitialize]
public void BuildUp()
{
- concreteHeartbeat = new ConcreteHeartbeatTestClass();
+ concreteHeartbeat1 = new ConcreteHeartbeatTestClass();
+ concreteHeartbeat2 = new ConcreteHeartbeatTestClass();
+ concreteHeartbeat3 = new ConcreteHeartbeatTestClass();
}
[TestCleanup]
@@ -23,9 +27,21 @@ public void TearDown()
[TestMethod]
public void TestBringDownHeartbeatThread()
{
- Assert.IsTrue(concreteHeartbeat.IsConsideredAlive());
+ Assert.IsTrue(concreteHeartbeat1.IsConsideredAlive());
- concreteHeartbeat.BringDownHeartbeatThread();
+ concreteHeartbeat1.BringDownHeartbeatThread();
+
+ // This is aserting true on true because if the BringDownHeartbeatThread doesn't
+ // terminate correctly, it will never reach this line and fail.
+ Assert.IsTrue(true);
+ }
+
+ [TestMethod]
+ public void TestBringDownDueToMiscommunication()
+ {
+ Assert.IsTrue(concreteHeartbeat2.IsConsideredAlive());
+
+ concreteHeartbeat2.BringDownDueToMiscommunication();
// This is aserting true on true because if the BringDownHeartbeatThread doesn't
// terminate correctly, it will never reach this line and fail.
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/EntitiesTests/HeartbeatTrackerContainerTest.cs b/ControlRoomApplication/ControlRoomApplicationTest/EntitiesTests/HeartbeatTrackerContainerTest.cs
index 2d6fe10c..1a241bec 100644
--- a/ControlRoomApplication/ControlRoomApplicationTest/EntitiesTests/HeartbeatTrackerContainerTest.cs
+++ b/ControlRoomApplication/ControlRoomApplicationTest/EntitiesTests/HeartbeatTrackerContainerTest.cs
@@ -12,23 +12,21 @@ namespace ControlRoomApplicationTest.EntitiesTests
public class HeartbeatTrackerContainerTest
{
private SpectraCyberSimulatorController HBISCSController;
- private SimulationWeatherStation HBISimWeatherStation;
[TestInitialize]
public void BuildUp()
{
+ HeartbeatTrackerContainer.clearChildren();
HBISCSController = new SpectraCyberSimulatorController(new SpectraCyberSimulator());
HBISCSController.SetSpectraCyberModeType(SpectraCyberModeTypeEnum.CONTINUUM);
HBISCSController.BringUp();
- HBISimWeatherStation = new SimulationWeatherStation(100);
- HBISimWeatherStation.Start();
}
[TestMethod]
public void TestLifecycle()
{
- Assert.AreEqual(2, HeartbeatTrackerContainer.GetNumberOfChildren());
+ Assert.AreEqual(1, HeartbeatTrackerContainer.GetNumberOfChildren());
for (int i = 0; i < 5; i++)
{
@@ -38,12 +36,9 @@ public void TestLifecycle()
HeartbeatTrackerContainer.SafelyKillHeartbeatComponents();
- Assert.AreEqual(2, HeartbeatTrackerContainer.GetNumberOfChildren());
-
- HeartbeatTrackerContainer.StopTracking(HBISCSController);
Assert.AreEqual(1, HeartbeatTrackerContainer.GetNumberOfChildren());
- HeartbeatTrackerContainer.StopTracking(HBISimWeatherStation);
+ HeartbeatTrackerContainer.StopTracking(HBISCSController);
Assert.AreEqual(0, HeartbeatTrackerContainer.GetNumberOfChildren());
}
@@ -51,7 +46,6 @@ public void TestLifecycle()
public void BringDown()
{
HBISCSController.BringDown();
- HBISimWeatherStation.RequestKillAndJoin();
}
}
}
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/EntitiesTests/LocationTest.cs b/ControlRoomApplication/ControlRoomApplicationTest/EntitiesTests/LocationTest.cs
index 26a8695a..56ff738f 100644
--- a/ControlRoomApplication/ControlRoomApplicationTest/EntitiesTests/LocationTest.cs
+++ b/ControlRoomApplication/ControlRoomApplicationTest/EntitiesTests/LocationTest.cs
@@ -16,7 +16,7 @@ public class LocationTest
public void BuildUp()
{
// Initialize appointment entity
- location = new Location(longitude, latitude, altitude);
+ location = new Location(longitude, latitude, altitude, "");
}
[TestMethod]
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/EntitiesTests/OrientationTest.cs b/ControlRoomApplication/ControlRoomApplicationTest/EntitiesTests/OrientationTest.cs
index 611122ae..e6e50d1e 100644
--- a/ControlRoomApplication/ControlRoomApplicationTest/EntitiesTests/OrientationTest.cs
+++ b/ControlRoomApplication/ControlRoomApplicationTest/EntitiesTests/OrientationTest.cs
@@ -1,4 +1,5 @@
-using ControlRoomApplication.Entities;
+using ControlRoomApplication.Constants;
+using ControlRoomApplication.Entities;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace ControlRoomApplicationTest.EntitiesTests
@@ -79,5 +80,44 @@ public void TestNotEquals()
Assert.IsFalse(orientation_1.Equals(orientation_2));
}
+
+ [TestMethod]
+ public void TestOrientationValid()
+ {
+ const int SAFE_VAL = 50;
+
+ // Valid (low edge azimuth)
+ Orientation orientation;
+
+ // Valid (low edge elevation)
+ orientation = new Orientation(SAFE_VAL, SimulationConstants.LIMIT_LOW_EL_DEGREES);
+ Assert.IsTrue(orientation.orientationValid());
+
+ // Valid (high edge elevation)
+ orientation = new Orientation(SAFE_VAL, SimulationConstants.LIMIT_HIGH_EL_DEGREES);
+ Assert.IsTrue(orientation.orientationValid());
+
+ // Invalid (low elevation)
+ orientation = new Orientation(SAFE_VAL, SimulationConstants.LIMIT_LOW_EL_DEGREES - 1);
+ Assert.IsFalse(orientation.orientationValid());
+
+ // Invalid (high elevation)
+ orientation = new Orientation(SAFE_VAL, SimulationConstants.LIMIT_HIGH_EL_DEGREES + 1);
+ Assert.IsFalse(orientation.orientationValid());
+ }
+
+ [TestMethod]
+ public void TestCloneOrientation()
+ {
+ // Create initial orientation
+ Orientation initial = new Orientation(123, 456);
+
+ // Clone initial orientation
+ Orientation cloned = (Orientation)initial.Clone();
+
+ // Verify cloned orientation's azimuth and elevation are the same
+ Assert.AreEqual(initial.Azimuth, cloned.Azimuth);
+ Assert.AreEqual(initial.Elevation, cloned.Elevation);
+ }
}
}
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/EntitiesTests/PLCCommandAndQueryTypeEnumTest.cs b/ControlRoomApplication/ControlRoomApplicationTest/EntitiesTests/PLCCommandAndQueryTypeEnumTest.cs
deleted file mode 100644
index b2fd0f1e..00000000
--- a/ControlRoomApplication/ControlRoomApplicationTest/EntitiesTests/PLCCommandAndQueryTypeEnumTest.cs
+++ /dev/null
@@ -1,67 +0,0 @@
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using ControlRoomApplication.Entities;
-
-namespace ControlRoomApplicationTest.EntitiesTests
-{
- [TestClass]
- public class PLCCommandAndQueryTypeEnumTest
- {
- private PLCCommandAndQueryTypeEnum _input_undefined;
- private PLCCommandAndQueryTypeEnum _input_test_connection;
- private PLCCommandAndQueryTypeEnum _input_get_current_azel_positions;
- private PLCCommandAndQueryTypeEnum _input_get_current_limit_switch_statuses;
- private PLCCommandAndQueryTypeEnum _input_get_current_safety_interlock_status;
- private PLCCommandAndQueryTypeEnum _input_cancel_active_objective_azel_position;
- private PLCCommandAndQueryTypeEnum _input_shutdown;
- private PLCCommandAndQueryTypeEnum _input_calibrate;
- private PLCCommandAndQueryTypeEnum _input_set_objective_azel_position;
-
- [TestInitialize]
- public void BuildUp()
- {
- _input_undefined = PLCCommandAndQueryTypeEnum.UNDEFINED;
- _input_test_connection = PLCCommandAndQueryTypeEnum.TEST_CONNECTION;
- _input_get_current_azel_positions = PLCCommandAndQueryTypeEnum.GET_CURRENT_AZEL_POSITIONS;
- _input_get_current_limit_switch_statuses = PLCCommandAndQueryTypeEnum.GET_CURRENT_LIMIT_SWITCH_STATUSES;
- _input_get_current_safety_interlock_status = PLCCommandAndQueryTypeEnum.GET_CURRENT_SAFETY_INTERLOCK_STATUS;
- _input_cancel_active_objective_azel_position = PLCCommandAndQueryTypeEnum.CANCEL_ACTIVE_OBJECTIVE_AZEL_POSITION;
- _input_shutdown = PLCCommandAndQueryTypeEnum.SHUTDOWN;
- _input_calibrate = PLCCommandAndQueryTypeEnum.CALIBRATE;
- _input_set_objective_azel_position = PLCCommandAndQueryTypeEnum.SET_OBJECTIVE_AZEL_POSITION;
- }
-
- [TestMethod]
- public void TestPLCCommandAndQueryTypeEnumHelper()
- {
- Assert.AreEqual(0x0, PLCCommandAndQueryTypeConversionHelper.ConvertToByte(_input_undefined));
- Assert.AreEqual(PLCCommandAndQueryTypeEnum.UNDEFINED, PLCCommandAndQueryTypeConversionHelper.GetFromByte(0x0));
-
- Assert.AreEqual(0x1, PLCCommandAndQueryTypeConversionHelper.ConvertToByte(_input_test_connection));
- Assert.AreEqual(PLCCommandAndQueryTypeEnum.TEST_CONNECTION, PLCCommandAndQueryTypeConversionHelper.GetFromByte(0x1));
-
- Assert.AreEqual(0x2, PLCCommandAndQueryTypeConversionHelper.ConvertToByte(_input_get_current_azel_positions));
- Assert.AreEqual(PLCCommandAndQueryTypeEnum.GET_CURRENT_AZEL_POSITIONS, PLCCommandAndQueryTypeConversionHelper.GetFromByte(0x2));
-
- Assert.AreEqual(0x3, PLCCommandAndQueryTypeConversionHelper.ConvertToByte(_input_get_current_limit_switch_statuses));
- Assert.AreEqual(PLCCommandAndQueryTypeEnum.GET_CURRENT_LIMIT_SWITCH_STATUSES, PLCCommandAndQueryTypeConversionHelper.GetFromByte(0x3));
-
- Assert.AreEqual(0x4, PLCCommandAndQueryTypeConversionHelper.ConvertToByte(_input_get_current_safety_interlock_status));
- Assert.AreEqual(PLCCommandAndQueryTypeEnum.GET_CURRENT_SAFETY_INTERLOCK_STATUS, PLCCommandAndQueryTypeConversionHelper.GetFromByte(0x4));
-
- Assert.AreEqual(0x5, PLCCommandAndQueryTypeConversionHelper.ConvertToByte(_input_cancel_active_objective_azel_position));
- Assert.AreEqual(PLCCommandAndQueryTypeEnum.CANCEL_ACTIVE_OBJECTIVE_AZEL_POSITION, PLCCommandAndQueryTypeConversionHelper.GetFromByte(0x5));
-
- Assert.AreEqual(0x6, PLCCommandAndQueryTypeConversionHelper.ConvertToByte(_input_shutdown));
- Assert.AreEqual(PLCCommandAndQueryTypeEnum.SHUTDOWN, PLCCommandAndQueryTypeConversionHelper.GetFromByte(0x6));
-
- Assert.AreEqual(0x7, PLCCommandAndQueryTypeConversionHelper.ConvertToByte(_input_calibrate));
- Assert.AreEqual(PLCCommandAndQueryTypeEnum.CALIBRATE, PLCCommandAndQueryTypeConversionHelper.GetFromByte(0x7));
-
- //Assert.AreEqual(0x8, PLCCommandAndQueryTypeConversionHelper.ConvertToByte(_input_set_objective_azel_position));
- //the above test fails becasue the falue of _input_set_objective_azel_position is set to 0xb but their testing it against 0x8
- //i don't intend to use the comand and querrie schema the previous team set up because it is not compatable with the modbus that the plc uses
- //thus i am leaving this test failing (jacob minor)
- //Assert.AreEqual(PLCCommandAndQueryTypeEnum.SET_OBJECTIVE_AZEL_POSITION, PLCCommandAndQueryTypeConversionHelper.GetFromByte(0x8));
- }
- }
-}
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/EntitiesTests/PLCCommandResponseExpectationEnumTest.cs b/ControlRoomApplication/ControlRoomApplicationTest/EntitiesTests/PLCCommandResponseExpectationEnumTest.cs
deleted file mode 100644
index fdce5fc7..00000000
--- a/ControlRoomApplication/ControlRoomApplicationTest/EntitiesTests/PLCCommandResponseExpectationEnumTest.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using System;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using ControlRoomApplication.Entities;
-
-namespace ControlRoomApplicationTest.EntitiesTests
-{
- [TestClass]
- public class PLCCommandResponseExpectationEnumTest
- {
- [TestMethod]
- public void TestEnumToByte()
- {
- Assert.AreEqual(0x0, PLCCommandResponseExpectationConversionHelper.ConvertToByte(PLCCommandResponseExpectationEnum.UNDEFINED));
- Assert.AreEqual(0x1, PLCCommandResponseExpectationConversionHelper.ConvertToByte(PLCCommandResponseExpectationEnum.MINOR_RESPONSE));
- Assert.AreEqual(0x2, PLCCommandResponseExpectationConversionHelper.ConvertToByte(PLCCommandResponseExpectationEnum.FULL_RESPONSE));
- }
-
- [TestMethod]
- public void TestByteToEnum()
- {
- Assert.AreEqual(PLCCommandResponseExpectationEnum.UNDEFINED, PLCCommandResponseExpectationConversionHelper.GetFromByte(0x0));
- Assert.AreEqual(PLCCommandResponseExpectationEnum.MINOR_RESPONSE, PLCCommandResponseExpectationConversionHelper.GetFromByte(0x1));
- Assert.AreEqual(PLCCommandResponseExpectationEnum.FULL_RESPONSE, PLCCommandResponseExpectationConversionHelper.GetFromByte(0x2));
- Assert.AreEqual(PLCCommandResponseExpectationEnum.UNDEFINED, PLCCommandResponseExpectationConversionHelper.GetFromByte(0x3));
- Assert.AreEqual(PLCCommandResponseExpectationEnum.UNDEFINED, PLCCommandResponseExpectationConversionHelper.GetFromByte(0xFF));
- }
- }
-}
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/EntitiesTests/RFDataTest.cs b/ControlRoomApplication/ControlRoomApplicationTest/EntitiesTests/RFDataTest.cs
index 6c5af1e2..aeed14f0 100644
--- a/ControlRoomApplication/ControlRoomApplicationTest/EntitiesTests/RFDataTest.cs
+++ b/ControlRoomApplication/ControlRoomApplicationTest/EntitiesTests/RFDataTest.cs
@@ -28,7 +28,7 @@ public void BuildUp()
apptId = 1;
appt.Id = apptId;
DateTime start = DateTime.UtcNow;
- appt.StartTime = start;
+ appt.start_time = start;
}
[TestMethod]
@@ -47,7 +47,7 @@ public void TestSettersAndGetters()
Assert.AreEqual(id, rfdata.Id);
Assert.AreEqual(timeCaptured, rfdata.TimeCaptured);
Assert.AreEqual(intensity, rfdata.Intensity);
- Assert.AreEqual(appt.StartTime.Date, rfdata.Appointment.StartTime.Date);
+ Assert.AreEqual(appt.start_time.Date, rfdata.Appointment.start_time.Date);
}
[TestMethod]
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/EntitiesTests/RadioTelescopeConfigTest.cs b/ControlRoomApplication/ControlRoomApplicationTest/EntitiesTests/RadioTelescopeConfigTest.cs
new file mode 100644
index 00000000..9bdf4c40
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplicationTest/EntitiesTests/RadioTelescopeConfigTest.cs
@@ -0,0 +1,90 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using ControlRoomApplication.Entities;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+
+namespace ControlRoomApplication.EntitiesTests {
+
+ [TestClass]
+ public class RadioTelescopeConfigTest {
+ private string validJson1 = "{\"telescopeID\":134,\"newTelescope\":false}";
+ private string validJson2 = "{\"telescopeID\":1,\"newTelescope\":true}";
+ private string validJson3 = "{\"telescopeID\":100,\"newTelescope\":false}";
+ private string invalidJson1 = "{\"telescopeID\":,\"newTelescope\":}";
+ private string invalidJson2 = "{\"telescopeID\":adasd,\"newTelescope\":dff}";
+ private string invalidJson3 = "";
+ private string invalidJson4 = "\"telescopeID\":adasd\"newTelescope\":dff}";
+ public RadioTelescopeConfig rtc1 = new RadioTelescopeConfig(134, false);
+ public RadioTelescopeConfig rtc2 = new RadioTelescopeConfig(1, true);
+ public RadioTelescopeConfig rtc3 = new RadioTelescopeConfig(100, false);
+
+ [TestMethod]
+ public void TestDeserializeAndSerialize()
+ {
+ // Each one of these tests will attempt to serialize a given RTConfig instance, write it to the JSON file, and then
+ // retrieve the contents by deserializing the file.
+ // IF things work as they should, the test object which is being pulled from the JSON file should
+ // match the one placed in it by SerializeRTConfig
+ RadioTelescopeConfig.SerializeRTConfig(rtc1, true);
+ RadioTelescopeConfig rtcTest1 = RadioTelescopeConfig.DeserializeRTConfig(true);
+ Assert.AreEqual(rtcTest1.telescopeID, rtc1.telescopeID);
+ Assert.AreEqual(rtcTest1.newTelescope, rtc1.newTelescope);
+
+ RadioTelescopeConfig.SerializeRTConfig(rtc2, true);
+ RadioTelescopeConfig rtcTest2 = RadioTelescopeConfig.DeserializeRTConfig(true);
+ Assert.AreEqual(rtcTest2.telescopeID, rtc2.telescopeID);
+ Assert.AreEqual(rtcTest2.newTelescope, rtc2.newTelescope);
+
+ RadioTelescopeConfig.SerializeRTConfig(rtc3, true);
+ RadioTelescopeConfig rtcTest3 = RadioTelescopeConfig.DeserializeRTConfig(true);
+ Assert.AreEqual(rtcTest3.telescopeID, rtc3.telescopeID);
+ Assert.AreEqual(rtcTest3.newTelescope, rtc3.newTelescope);
+
+ }
+
+ [TestMethod]
+ public void TestCreateAndWriteToJSONFile()
+ {
+ // In these tests, we are passing invalid and valid JSON strings to the file. The expected behavior
+ // is that the DeserializeRTConfig should return null if a JsonReaderException occurs (which, for an invalid JSON string, will occur).
+
+ // In the valid JSON instances, the resulting objects should match the values of the validJsonX strings.
+ RadioTelescopeConfig.CreateAndWriteToNewJSONFile(validJson1, true);
+ RadioTelescopeConfig rtcTest1 = RadioTelescopeConfig.DeserializeRTConfig(true);
+ Assert.AreEqual(rtcTest1.telescopeID, 134);
+ Assert.AreEqual(rtcTest1.newTelescope, false);
+
+ RadioTelescopeConfig.CreateAndWriteToNewJSONFile(validJson2, true);
+ RadioTelescopeConfig rtcTest2 = RadioTelescopeConfig.DeserializeRTConfig(true);
+ Assert.AreEqual(rtcTest2.telescopeID, 1);
+ Assert.AreEqual(rtcTest2.newTelescope, true);
+
+ RadioTelescopeConfig.CreateAndWriteToNewJSONFile(validJson3, true);
+ RadioTelescopeConfig rtcTest3 = RadioTelescopeConfig.DeserializeRTConfig(true);
+ Assert.AreEqual(rtcTest3.telescopeID, 100);
+ Assert.AreEqual(rtcTest3.newTelescope, false);
+
+
+ // For the invalid instances, the DeserializeRTConfig method will return null due to the JsonReaderException
+ RadioTelescopeConfig.CreateAndWriteToNewJSONFile(invalidJson1, true);
+ RadioTelescopeConfig rtcTest4 = RadioTelescopeConfig.DeserializeRTConfig(true);
+ Assert.IsNull(rtcTest4);
+
+ RadioTelescopeConfig.CreateAndWriteToNewJSONFile(invalidJson2, true);
+ RadioTelescopeConfig rtcTest5 = RadioTelescopeConfig.DeserializeRTConfig(true);
+ Assert.IsNull(rtcTest5);
+
+ RadioTelescopeConfig.CreateAndWriteToNewJSONFile(invalidJson3, true);
+ RadioTelescopeConfig rtcTest6 = RadioTelescopeConfig.DeserializeRTConfig(true);
+ Assert.IsNull(rtcTest6);
+
+ RadioTelescopeConfig.CreateAndWriteToNewJSONFile(invalidJson4, true);
+ RadioTelescopeConfig rtcTest7 = RadioTelescopeConfig.DeserializeRTConfig(true);
+ Assert.IsNull(rtcTest7);
+ }
+
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/EntitiesTests/SensorNetworkConfigTest.cs b/ControlRoomApplication/ControlRoomApplicationTest/EntitiesTests/SensorNetworkConfigTest.cs
new file mode 100644
index 00000000..35fde9ca
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplicationTest/EntitiesTests/SensorNetworkConfigTest.cs
@@ -0,0 +1,229 @@
+using ControlRoomApplication.Controllers.SensorNetwork;
+using ControlRoomApplication.Entities;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ControlRoomApplicationTest.EntitiesTests
+{
+ [TestClass]
+ public class SensorNetworkConfigTest
+ {
+ [TestMethod]
+ public void TestInitialization()
+ {
+ int telescopeId = 5;
+
+ // Create new SensorNetworkConfig with a telescope ID of 5
+ SensorNetworkConfig config = new SensorNetworkConfig(telescopeId);
+
+ // telescope ID
+ Assert.AreEqual(config.TelescopeId, telescopeId);
+
+ // default constants
+ Assert.AreEqual(config.TimeoutDataRetrieval, SensorNetworkConstants.DefaultDataRetrievalTimeout);
+ Assert.AreEqual(config.TimeoutInitialization, SensorNetworkConstants.DefaultInitializationTimeout);
+
+ // default initialization (all must default to true)
+ Assert.AreEqual(config.ElevationTemp1Init, true);
+ Assert.AreEqual(config.AzimuthTemp1Init, true);
+ Assert.AreEqual(config.ElevationAccelerometerInit, true);
+ Assert.AreEqual(config.AzimuthAccelerometerInit, true);
+ Assert.AreEqual(config.CounterbalanceAccelerometerInit, true);
+ Assert.AreEqual(config.ElevationEncoderInit, true);
+ Assert.AreEqual(config.AzimuthEncoderInit, true);
+ }
+
+ [TestMethod]
+ public void TestEmptyInitialization()
+ {
+ SensorNetworkConfig config = new SensorNetworkConfig();
+
+ // All values should be an equivalent of 0
+
+ Assert.AreEqual(config.TelescopeId, 0);
+
+ Assert.AreEqual(config.TimeoutDataRetrieval, 0);
+ Assert.AreEqual(config.TimeoutInitialization, 0);
+
+ Assert.AreEqual(config.ElevationTemp1Init, false);
+ Assert.AreEqual(config.AzimuthTemp1Init, false);
+ Assert.AreEqual(config.ElevationAccelerometerInit, false);
+ Assert.AreEqual(config.AzimuthAccelerometerInit, false);
+ Assert.AreEqual(config.CounterbalanceAccelerometerInit, false);
+ Assert.AreEqual(config.ElevationEncoderInit, false);
+ Assert.AreEqual(config.AzimuthEncoderInit, false);
+ }
+
+ [TestMethod]
+ public void TestEquals_Identical_Equal()
+ {
+ int telescopeId = 5;
+
+ SensorNetworkConfig config = new SensorNetworkConfig(telescopeId);
+
+ SensorNetworkConfig other = new SensorNetworkConfig(telescopeId);
+
+ Assert.IsTrue(config.Equals(other));
+ }
+
+ [TestMethod]
+ public void TestEquals_TelescopeIdDifferent_NotEqual()
+ {
+ SensorNetworkConfig config = new SensorNetworkConfig(5);
+ SensorNetworkConfig other = new SensorNetworkConfig(6);
+
+ Assert.IsFalse(config.Equals(other));
+ }
+
+ [TestMethod]
+ public void TestEquals_ElevationTemp1InitDifferent_NotEqual()
+ {
+ int telescopeId = 5;
+
+ SensorNetworkConfig config = new SensorNetworkConfig(telescopeId);
+ SensorNetworkConfig other = new SensorNetworkConfig(telescopeId);
+
+ other.ElevationTemp1Init = false;
+
+ Assert.IsFalse(config.Equals(other));
+ }
+
+ [TestMethod]
+ public void TestEquals_AzimuthTemp1InitDifferent_NotEqual()
+ {
+ int telescopeId = 5;
+
+ SensorNetworkConfig config = new SensorNetworkConfig(telescopeId);
+ SensorNetworkConfig other = new SensorNetworkConfig(telescopeId);
+
+ other.AzimuthTemp1Init = false;
+
+ Assert.IsFalse(config.Equals(other));
+ }
+
+ [TestMethod]
+ public void TestEquals_AzimuthAccelerometerInitDifferent_NotEqual()
+ {
+ int telescopeId = 5;
+
+ SensorNetworkConfig config = new SensorNetworkConfig(telescopeId);
+ SensorNetworkConfig other = new SensorNetworkConfig(telescopeId);
+
+ other.AzimuthAccelerometerInit = false;
+
+ Assert.IsFalse(config.Equals(other));
+ }
+
+ [TestMethod]
+ public void TestEquals_ElevationAccelerometerInitDifferent_NotEqual()
+ {
+ int telescopeId = 5;
+
+ SensorNetworkConfig config = new SensorNetworkConfig(telescopeId);
+ SensorNetworkConfig other = new SensorNetworkConfig(telescopeId);
+
+ other.ElevationAccelerometerInit = false;
+
+ Assert.IsFalse(config.Equals(other));
+ }
+
+ [TestMethod]
+ public void TestEquals_CounterbalanceAccelerometerInitDifferent_NotEqual()
+ {
+ int telescopeId = 5;
+
+ SensorNetworkConfig config = new SensorNetworkConfig(telescopeId);
+ SensorNetworkConfig other = new SensorNetworkConfig(telescopeId);
+
+ other.CounterbalanceAccelerometerInit = false;
+
+ Assert.IsFalse(config.Equals(other));
+ }
+
+ [TestMethod]
+ public void TestEquals_AzimuthEncoderInitDifferent_NotEqual()
+ {
+ int telescopeId = 5;
+
+ SensorNetworkConfig config = new SensorNetworkConfig(telescopeId);
+ SensorNetworkConfig other = new SensorNetworkConfig(telescopeId);
+
+ other.AzimuthEncoderInit = false;
+
+ Assert.IsFalse(config.Equals(other));
+ }
+
+ [TestMethod]
+ public void TestEquals_ElevationEncoderInitDifferent_NotEqual()
+ {
+ int telescopeId = 5;
+
+ SensorNetworkConfig config = new SensorNetworkConfig(telescopeId);
+ SensorNetworkConfig other = new SensorNetworkConfig(telescopeId);
+
+ other.ElevationEncoderInit = false;
+
+ Assert.IsFalse(config.Equals(other));
+ }
+
+ [TestMethod]
+ public void TestEquals_TimeoutDataRetrievalDifferent_NotEqual()
+ {
+ int telescopeId = 5;
+
+ SensorNetworkConfig config = new SensorNetworkConfig(telescopeId);
+ SensorNetworkConfig other = new SensorNetworkConfig(telescopeId);
+
+ other.TimeoutDataRetrieval = 5;
+
+ Assert.IsFalse(config.Equals(other));
+ }
+
+ [TestMethod]
+ public void TestEquals_TimeoutInitializationDifferent_NotEqual()
+ {
+ int telescopeId = 5;
+
+ SensorNetworkConfig config = new SensorNetworkConfig(telescopeId);
+ SensorNetworkConfig other = new SensorNetworkConfig(telescopeId);
+
+ other.TimeoutInitialization = 5;
+
+ Assert.IsFalse(config.Equals(other));
+ }
+
+ [TestMethod]
+ public void TestGetSensorInitAsBytes_AllTrue_AllBytesOne()
+ {
+ SensorNetworkConfig config = new SensorNetworkConfig(5);
+
+ var bytes = config.GetSensorInitAsBytes();
+
+ // All bytes in the array should be 1
+ Assert.IsTrue(bytes.All(singleByte => singleByte == 1));
+ }
+
+ [TestMethod]
+ public void TestGetSensorInitAsBytes_AllTrue_AllBytesZero()
+ {
+ SensorNetworkConfig config = new SensorNetworkConfig(5);
+
+ config.ElevationTemp1Init = false;
+ config.AzimuthTemp1Init = false;
+ config.ElevationAccelerometerInit = false;
+ config.AzimuthAccelerometerInit = false;
+ config.CounterbalanceAccelerometerInit = false;
+ config.ElevationEncoderInit = false;
+ config.AzimuthEncoderInit = false;
+
+ var bytes = config.GetSensorInitAsBytes();
+
+ // All bytes in the array should be 0
+ Assert.IsTrue(bytes.All(singleByte => singleByte == 0));
+ }
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/EntitiesTests/SpectraCyberConfigTest.cs b/ControlRoomApplication/ControlRoomApplicationTest/EntitiesTests/SpectraCyberConfigTest.cs
index 024a9ac3..12b9509d 100644
--- a/ControlRoomApplication/ControlRoomApplicationTest/EntitiesTests/SpectraCyberConfigTest.cs
+++ b/ControlRoomApplication/ControlRoomApplicationTest/EntitiesTests/SpectraCyberConfigTest.cs
@@ -30,7 +30,7 @@ public void BuildUp()
[TestMethod]
public void TestGettersAndSetters()
{
- Assert.AreEqual(mode, spectraCyberConfig_1.Mode);
+ Assert.AreEqual(mode, spectraCyberConfig_1._Mode);
Assert.AreEqual(integration_time, spectraCyberConfig_1.IntegrationTime);
Assert.AreEqual(offset_voltage_1, spectraCyberConfig_1.OffsetVoltage);
Assert.AreEqual(if_gain, spectraCyberConfig_1.IFGain);
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/EntitiesTests/TemperatureTest.cs b/ControlRoomApplication/ControlRoomApplicationTest/EntitiesTests/TemperatureTest.cs
new file mode 100644
index 00000000..ef8de9fb
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplicationTest/EntitiesTests/TemperatureTest.cs
@@ -0,0 +1,62 @@
+using ControlRoomApplication.Entities;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System;
+
+namespace ControlRoomApplicationTest.EntitiesTests
+{
+ [TestClass]
+ public class TemperatureTest
+ {
+ // Class being tested
+ private Temperature Temperature;
+
+ [TestInitialize]
+ public void BuildUp()
+ {
+
+ }
+
+ [TestMethod]
+ public void TestGettersAndSetters()
+ {
+ // Initialize appointment entity
+ SensorLocationEnum loc1 = SensorLocationEnum.AZ_MOTOR;
+ SensorLocationEnum loc2 = SensorLocationEnum.EL_MOTOR;
+
+ //Generate current time
+ long dateTime1 = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
+ long dateTime2 = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
+
+ //Generate Temperature
+ Temperature t1 = Temperature.Generate(dateTime1, 0.0, loc1);
+
+ t1.TimeCapturedUTC = dateTime2;
+ Assert.AreEqual(t1.TimeCapturedUTC, dateTime2);
+ t1.temp = 100.0;
+ Assert.AreEqual(t1.temp, 100.0);
+ t1.location_ID =1;
+ Assert.AreEqual(t1.location_ID, 1);
+
+ }
+
+ [TestMethod]
+ public void TestEquals()
+ {
+ // Initialize appointment entity
+ SensorLocationEnum loc1 = SensorLocationEnum.AZ_MOTOR;
+
+ //Generate current time
+ long dateTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
+
+ //Generate Temperature
+ Temperature t1 = Temperature.Generate(dateTime, 0.0, loc1);
+ Temperature t2 = Temperature.Generate(dateTime, 2.0, loc1);
+
+
+ Assert.AreEqual(t1, t1);
+ Assert.AreNotEqual(t1, t2);
+ Assert.AreNotEqual(t2, t1);
+ }
+ }
+}
+
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/AbstractPLCDriverTest.cs b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/AbstractPLCDriverTest.cs
index 3d2d11e1..f76dc748 100644
--- a/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/AbstractPLCDriverTest.cs
+++ b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/AbstractPLCDriverTest.cs
@@ -2,32 +2,41 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using ControlRoomApplication.Controllers;
using ControlRoomApplication.Constants;
+using System.Threading;
-namespace ControlRoomApplicationTest.EntityControllersTests
-{
+namespace ControlRoomApplicationTest.EntityControllersTests {
[TestClass]
- public class AbstractPLCDriverTest
- {
+ public class AbstractPLCDriverTest {
public static TestPLCDriver DerivedAbstractPLCDriver;
-
+ /*
[ClassInitialize]
- public static void BringUp(TestContext context)
- {
- DerivedAbstractPLCDriver = new TestPLCDriver(PLCConstants.LOCAL_HOST_IP, PLCConstants.LOCAL_HOST_IP,8089, 8089);
- }
-
- [TestMethod]
- public void TestStartAndStopAsync()
- {
- Assert.AreEqual(true, DerivedAbstractPLCDriver.StartAsyncAcceptingClients());
- Assert.AreEqual(true, DerivedAbstractPLCDriver.RequestStopAsyncAcceptingClientsAndJoin());
+ public static void BringUp( TestContext context ) {
+ DerivedAbstractPLCDriver = new TestPLCDriver( PLCConstants.LOCAL_HOST_IP , PLCConstants.LOCAL_HOST_IP , 8089 , 8089 , false );
}
[ClassCleanup]
- public static void Bringdown( ) {
+ public static void Bringdown() {
//DerivedAbstractPLCDriver.Calibrate();
DerivedAbstractPLCDriver.Bring_down();
DerivedAbstractPLCDriver = null;
}
+ //*/
+ [TestCleanup]
+ public void testClean() {
+ //DerivedAbstractPLCDriver.Bring_down();
+ DerivedAbstractPLCDriver = null;
+ }
+
+ [TestInitialize]
+ public void testInit() {
+ DerivedAbstractPLCDriver = new TestPLCDriver( PLCConstants.LOCAL_HOST_IP , PLCConstants.LOCAL_HOST_IP , 8089 , 8089 , false );
+ }
+
+ [TestMethod]
+ public void TestStartAndStopAsync() {
+ Assert.AreEqual( true , DerivedAbstractPLCDriver.StartAsyncAcceptingClients() );
+ Thread.Sleep( 200 );
+ Assert.AreEqual( true , DerivedAbstractPLCDriver.RequestStopAsyncAcceptingClientsAndJoin() );
+ }
}
}
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/ControlRoomControllerTest.cs b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/ControlRoomControllerTest.cs
index 4302bdf9..8289ef5b 100644
--- a/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/ControlRoomControllerTest.cs
+++ b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/ControlRoomControllerTest.cs
@@ -4,6 +4,9 @@
using ControlRoomApplication.Constants;
using ControlRoomApplication.Entities;
using ControlRoomApplication.Simulators.Hardware.WeatherStation;
+using System.Net.Sockets;
+using System.Net;
+using ControlRoomApplication.Controllers.SensorNetwork;
namespace ControlRoomApplicationTest.EntityControllersTests
{
@@ -14,54 +17,86 @@ public class ControlRoomControllerTest
public static ControlRoom ControlRoom;
public static Orientation CalibrationOrientation;
public static string IP = PLCConstants.LOCAL_HOST_IP;
- public static int Port = 8094;
+ public static int Port1 = 15001;
+ public static int Port2 = 15003;
public static RadioTelescopeController RTController0;
public static RadioTelescopeController RTController1;
public static RadioTelescopeController RTController2;
+
+ public static IPAddress SnServerIp = IPAddress.Parse("127.0.0.1");
+ public static int SnServerPort = 3000;
+ public static string SnClientIp = "127.0.0.1";
+ public static int SnClientPort = 3001;
+ public static int SnTelescopeId = 3000;
+
[ClassInitialize]
public static void BringUp(TestContext context)
{
- ControlRoom = new ControlRoom(new SimulationWeatherStation(100));
+ ControlRoom = new ControlRoom(new SimulationWeatherStation(100), 81);
+
+ // End the CR's listener's server. We have to do this until we stop hard-coding that dang value.
+ // TODO: Remove this logic when the value is no longer hard-coded (issue #350)
+ // PrivateObject listener = new PrivateObject(ControlRoom.mobileControlServer);
+ //((TcpListener)listener.GetFieldOrProperty("server")).Stop();
+
CRController = new ControlRoomController(ControlRoom);
CalibrationOrientation = new Orientation(0, 90);
}
+
+
[TestInitialize]
public void ReinitializeRTs()
{
+
+ SensorNetworkServer server = new SensorNetworkServer(SnServerIp, SnServerPort, SnClientIp, SnClientPort, SnTelescopeId, true);
+
+
RTController0 = new RadioTelescopeController(
new RadioTelescope(
new SpectraCyberSimulatorController(new SpectraCyberSimulator()),
- new TestPLCDriver(IP, IP, Port, Port),
+ new TestPLCDriver(IP, IP, Port1, Port2, true),
MiscellaneousConstants.JOHN_RUDY_PARK,
- CalibrationOrientation
+ CalibrationOrientation,1,server
)
);
RTController1 = new RadioTelescopeController(
new RadioTelescope(
new SpectraCyberSimulatorController(new SpectraCyberSimulator()),
- new TestPLCDriver(IP, IP, Port+3, Port+3),
+ new TestPLCDriver(IP, IP, Port1 + 3, Port2 + 3,true),
MiscellaneousConstants.JOHN_RUDY_PARK,
- CalibrationOrientation
+ CalibrationOrientation,2,server
)
);
RTController2 = new RadioTelescopeController(
new RadioTelescope(
new SpectraCyberSimulatorController(new SpectraCyberSimulator()),
- new TestPLCDriver(IP, IP, Port+6, Port+6),
+ new TestPLCDriver(IP, IP, Port1 + 6, Port2 + 6,true),
MiscellaneousConstants.JOHN_RUDY_PARK,
- CalibrationOrientation
+ CalibrationOrientation,3,server
)
);
+
+
+
+ }
+
+ [TestCleanup]
+ public void testClean() {
+ try {
+ RTController0.RadioTelescope.PLCDriver.Bring_down();
+ RTController1.RadioTelescope.PLCDriver.Bring_down();
+ RTController2.RadioTelescope.PLCDriver.Bring_down();
+ } catch { }
}
[TestMethod]
public void TestConstructorAndProperties()
{
- Assert.AreEqual(ControlRoom, CRController.ControlRoom);
+ Assert.IsTrue(ControlRoom == CRController.ControlRoom);
}
[TestMethod]
@@ -136,11 +171,23 @@ public void TestPreventRemoveMultipleTimes()
Assert.AreEqual(true, CRController.RemoveRadioTelescopeController(RTController0, true));
Assert.AreEqual(false, CRController.RemoveRadioTelescopeController(RTController0, true));
}
+
+ [TestMethod]
+ public void TestWeatherStationOverride()
+ {
+ CRController.ControlRoom.weatherStationOverride = false;
+ Assert.IsFalse(CRController.ControlRoom.weatherStationOverride);
+ CRController.ControlRoom.weatherStationOverride = true;
+ Assert.IsTrue(CRController.ControlRoom.weatherStationOverride);
+ }
+
[ClassCleanup]
public static void Bringdown( ) {
RTController0.RadioTelescope.PLCDriver.Bring_down();
RTController1.RadioTelescope.PLCDriver.Bring_down();
RTController2.RadioTelescope.PLCDriver.Bring_down();
+ CRController.ControlRoom.mobileControlServer.RequestToKillTCPMonitoringRoutine();
+
}
}
}
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/CoordinateCalculationControllerTest.cs b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/CoordinateCalculationControllerTest.cs
index 60fc5e47..0949d8db 100644
--- a/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/CoordinateCalculationControllerTest.cs
+++ b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/CoordinateCalculationControllerTest.cs
@@ -84,75 +84,100 @@ public void TestOrientationToCoordinate()
}
[TestMethod]
- public void TestCalculateOrientation()
+ public void TestCalculateOrientation_PointAppointment()
{
DateTime start = new DateTime(2018, 10, 30, 12, 0, 0);
DateTime end = new DateTime(2018, 10, 30, 13, 0, 0);
// Test point appointment
Appointment point_appt = new Appointment();
- point_appt.Type = AppointmentTypeEnum.POINT;
- point_appt.Status = AppointmentStatusEnum.REQUESTED;
- point_appt.StartTime = start;
- point_appt.EndTime = end;
+ point_appt._Type = AppointmentTypeEnum.POINT;
+ point_appt._Status = AppointmentStatusEnum.REQUESTED;
+ point_appt.start_time = start;
+ point_appt.end_time = end;
point_appt.Coordinates.Add(new Coordinate(0, 0));
var point_orientation = CoordinateCalculationController.CalculateOrientation(point_appt, start);
Assert.IsTrue(point_orientation != null);
+ }
+
+ [TestMethod]
+ public void TestCalculateOrientation_CelestialBodyAppointment()
+ {
+ DateTime start = new DateTime(2018, 10, 30, 12, 0, 0);
+ DateTime end = new DateTime(2018, 10, 30, 13, 0, 0);
// Test celesital body appointment
Appointment sun_appt = new Appointment();
- sun_appt.Type = AppointmentTypeEnum.CELESTIAL_BODY;
- sun_appt.Status = AppointmentStatusEnum.REQUESTED;
- sun_appt.StartTime = start;
- sun_appt.EndTime = end;
+ sun_appt._Type = AppointmentTypeEnum.CELESTIAL_BODY;
+ sun_appt._Status = AppointmentStatusEnum.REQUESTED;
+ sun_appt.start_time = start;
+ sun_appt.end_time = end;
sun_appt.CelestialBody = new CelestialBody(CelestialBodyConstants.SUN);
var sun_orientation = CoordinateCalculationController.CalculateOrientation(sun_appt, start);
Assert.IsTrue(sun_orientation != null);
+ }
+
+ [TestMethod]
+ public void TestCalculateOrientation_RasterAppointment()
+ {
+ DateTime start = new DateTime(2018, 10, 30, 12, 0, 0);
+ DateTime end = new DateTime(2018, 10, 30, 13, 0, 0);
// Test raster appointment
Appointment raster_appt = new Appointment();
- raster_appt.Type = AppointmentTypeEnum.RASTER;
- raster_appt.Status = AppointmentStatusEnum.REQUESTED;
- raster_appt.StartTime = start;
- raster_appt.EndTime = end;
+ raster_appt._Type = AppointmentTypeEnum.RASTER;
+ raster_appt._Status = AppointmentStatusEnum.REQUESTED;
+ raster_appt.start_time = start;
+ raster_appt.end_time = end;
raster_appt.Coordinates.Add(new Coordinate(0, 0));
raster_appt.Coordinates.Add(new Coordinate(5, 5));
var raster_orientation = CoordinateCalculationController.CalculateOrientation(raster_appt, start);
Assert.IsTrue(raster_orientation != null);
+ }
+
+ [TestMethod]
+ public void TestCalculateOrientation_DriftScanAppointment()
+ {
+ DateTime start = new DateTime(2018, 10, 30, 12, 0, 0);
+ DateTime end = new DateTime(2018, 10, 30, 13, 0, 0);
// Test drift scan appointment
Appointment drift_scan_appt = new Appointment();
- drift_scan_appt.Type = AppointmentTypeEnum.DRIFT_SCAN;
- drift_scan_appt.Status = AppointmentStatusEnum.REQUESTED;
- drift_scan_appt.StartTime = start;
- drift_scan_appt.EndTime = end;
+ drift_scan_appt._Type = AppointmentTypeEnum.DRIFT_SCAN;
+ drift_scan_appt._Status = AppointmentStatusEnum.REQUESTED;
+ drift_scan_appt.start_time = start;
+ drift_scan_appt.end_time = end;
drift_scan_appt.Orientation = new Orientation(30, 30);
var orientation_orientation = CoordinateCalculationController.CalculateOrientation(drift_scan_appt, start);
Assert.IsTrue(orientation_orientation != null);
+ }
+
+ [TestMethod]
+ public void TestCalculateOrientation_FreeControlAppointment()
+ {
+ DateTime start = new DateTime(2018, 10, 30, 12, 0, 0);
+ DateTime end = new DateTime(2018, 10, 30, 13, 0, 0);
// Test free control appointment
Appointment free_control_appt = new Appointment();
- free_control_appt.Type = AppointmentTypeEnum.FREE_CONTROL;
- free_control_appt.Status = AppointmentStatusEnum.REQUESTED;
- free_control_appt.StartTime = start;
- free_control_appt.EndTime = end;
+ free_control_appt._Type = AppointmentTypeEnum.FREE_CONTROL;
+ free_control_appt._Status = AppointmentStatusEnum.REQUESTED;
+ free_control_appt.start_time = start;
+ free_control_appt.end_time = end;
free_control_appt.Orientation = new Orientation(30, 30);
- DatabaseOperations.AddAppointment(free_control_appt);
+ free_control_appt._Priority = AppointmentPriorityEnum.MANUAL;
var free_control_orientation_1 = CoordinateCalculationController.CalculateOrientation(free_control_appt, start);
- free_control_appt = DatabaseOperations.GetUpdatedAppointment(free_control_appt.Id);
Assert.IsTrue(free_control_orientation_1 != null);
Assert.IsTrue(free_control_appt.Orientation == null);
free_control_appt.Coordinates.Add(new Coordinate(0, 0));
- DatabaseOperations.UpdateAppointment(free_control_appt);
var free_control_orientation_2 = CoordinateCalculationController.CalculateOrientation(free_control_appt, end);
- free_control_appt = DatabaseOperations.GetUpdatedAppointment(free_control_appt.Id);
Assert.IsTrue(free_control_orientation_2 != null);
Assert.IsTrue(free_control_appt.Coordinates.Count == 0);
}
@@ -253,8 +278,8 @@ public void TestGetRasterOrientation()
DateTime start = new DateTime(2018, 10, 30, 12, 0, 0);
DateTime end = new DateTime(2018, 10, 30, 13, 0, 0);
var appt = new Appointment();
- appt.StartTime = start;
- appt.EndTime = end;
+ appt.start_time = start;
+ appt.end_time = end;
appt.Coordinates = new List();
var coord_1 = new Coordinate(12, 12);
var coord_2 = new Coordinate(15, 15);
@@ -277,8 +302,8 @@ public void TestGetRasterCoordinate()
DateTime start = new DateTime(2018, 10, 30, 12, 0, 0);
DateTime end = new DateTime(2018, 10, 30, 13, 0, 0);
var appt = new Appointment();
- appt.StartTime = start;
- appt.EndTime = end;
+ appt.start_time = start;
+ appt.end_time = end;
appt.Coordinates = new List();
var coord_1 = new Coordinate(12, 12);
var coord_2 = new Coordinate(15, 15);
@@ -300,8 +325,8 @@ public void TestGetDriftScanOrientation()
DateTime date = new DateTime(2018, 10, 30, 12, 0, 0);
Appointment drift_scan_appt = new Appointment();
- drift_scan_appt.Type = AppointmentTypeEnum.DRIFT_SCAN;
- drift_scan_appt.Status = AppointmentStatusEnum.REQUESTED;
+ drift_scan_appt._Type = AppointmentTypeEnum.DRIFT_SCAN;
+ drift_scan_appt._Status = AppointmentStatusEnum.REQUESTED;
Orientation test_orientation = new Orientation(30, 30);
drift_scan_appt.Orientation = test_orientation;
@@ -317,31 +342,27 @@ public void TestGetFreeControlOrientation()
// Test free control appointment
Appointment free_control_appt = new Appointment();
- free_control_appt.Type = AppointmentTypeEnum.FREE_CONTROL;
- free_control_appt.Status = AppointmentStatusEnum.REQUESTED;
+ free_control_appt._Type = AppointmentTypeEnum.FREE_CONTROL;
+ free_control_appt._Status = AppointmentStatusEnum.REQUESTED;
+ free_control_appt._Priority = AppointmentPriorityEnum.MANUAL;
Orientation test_orientation = new Orientation(30, 30);
free_control_appt.Orientation = test_orientation;
- DatabaseOperations.AddAppointment(free_control_appt);
// Test free control calibration
var free_control_orientation_1 = CoordinateCalculationController.CalculateOrientation(free_control_appt, date);
- free_control_appt = DatabaseOperations.GetUpdatedAppointment(free_control_appt.Id);
Assert.IsTrue(free_control_orientation_1.Elevation == test_orientation.Elevation);
Assert.IsTrue(free_control_orientation_1.Azimuth == test_orientation.Azimuth);
Assert.IsTrue(free_control_appt.Orientation == null);
// Test free control move
free_control_appt.Coordinates.Add(new Coordinate(0, 0));
- DatabaseOperations.UpdateAppointment(free_control_appt);
var free_control_orientation_2 = CoordinateCalculationController.CalculateOrientation(free_control_appt, date);
- free_control_appt = DatabaseOperations.GetUpdatedAppointment(free_control_appt.Id);
Assert.AreEqual(-37.14, free_control_orientation_2.Elevation, 0.05);
Assert.AreEqual(309.5, free_control_orientation_2.Azimuth, 0.05);
Assert.IsTrue(free_control_appt.Coordinates.Count == 0);
// Test free control move without coords
var free_control_orientation_3 = CoordinateCalculationController.CalculateOrientation(free_control_appt, date);
- free_control_appt = DatabaseOperations.GetUpdatedAppointment(free_control_appt.Id);
Assert.IsTrue(free_control_orientation_3 == null);
Assert.IsTrue(free_control_appt.Coordinates.Count == 0);
}
@@ -351,8 +372,9 @@ public void TestGetFreeControlCoordinate()
{
// Test free control appointment
Appointment free_control_appt = new Appointment();
- free_control_appt.Type = AppointmentTypeEnum.FREE_CONTROL;
- free_control_appt.Status = AppointmentStatusEnum.REQUESTED;
+ free_control_appt._Type = AppointmentTypeEnum.FREE_CONTROL;
+ free_control_appt._Status = AppointmentStatusEnum.REQUESTED;
+ free_control_appt._Priority = AppointmentPriorityEnum.MANUAL;
free_control_appt.Coordinates.Add(new Coordinate(0, 0));
// Test free control move
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/PLCClientAndDriverTest.cs b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/PLCClientAndDriverTest.cs
index 78ffae8c..0a3113fb 100644
--- a/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/PLCClientAndDriverTest.cs
+++ b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/PLCClientAndDriverTest.cs
@@ -6,6 +6,7 @@
namespace ControlRoomApplicationTest.EntityControllersTests
{
+ /*
[TestClass]
public class PLCClientAndDriverTest
{
@@ -135,4 +136,5 @@ public static void Cleanup()
TestDriver.RequestStopAsyncAcceptingClientsAndJoin();
}
}
+ */
}
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/RadioTelescopeControllerManagementThreadTest.cs b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/RadioTelescopeControllerManagementThreadTest.cs
index fa29ec58..99c570b2 100644
--- a/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/RadioTelescopeControllerManagementThreadTest.cs
+++ b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/RadioTelescopeControllerManagementThreadTest.cs
@@ -27,27 +27,28 @@ public class RadioTelescopeControllerManagementThreadTest
private static RadioTelescopeControllerManagementThread RTCMT1;
[TestInitialize]
- public void BringUp()
- {
+ public void BringUp() {
IP = PLCConstants.LOCAL_HOST_IP;
Port0 = 8112;
Port1 = 8115;
JohnRudyPark = MiscellaneousConstants.JOHN_RUDY_PARK;
- CalibrationOrientation = new Orientation(0, 90);
+ CalibrationOrientation = new Orientation( 0 , 90 );
- PLCCCH0 = new SimulationPLCDriver(IP, IP, Port0, Port0);
- RTC0 = new RadioTelescopeController(new RadioTelescope(new SpectraCyberSimulatorController(new SpectraCyberSimulator()), PLCCCH0, JohnRudyPark, CalibrationOrientation, 1));
- RTCMT0 = new RadioTelescopeControllerManagementThread(RTC0);
+ PLCCCH0 = new SimulationPLCDriver( IP , IP , Port0 , Port0 , true , false );
+ RTC0 = new RadioTelescopeController( new RadioTelescope( new SpectraCyberSimulatorController( new SpectraCyberSimulator() ) , PLCCCH0 , JohnRudyPark , CalibrationOrientation , 1 ) );
+ RTCMT0 = new RadioTelescopeControllerManagementThread( RTC0 );
- PLCCCH1 = new SimulationPLCDriver(IP, IP, Port1, Port1);
- RTC1 = new RadioTelescopeController(new RadioTelescope(new SpectraCyberSimulatorController(new SpectraCyberSimulator()), PLCCCH1, JohnRudyPark, CalibrationOrientation, 2));
- RTCMT1 = new RadioTelescopeControllerManagementThread(RTC1);
+ PLCCCH1 = new SimulationPLCDriver( IP , IP , Port1 , Port1 , true , false );
+ RTC1 = new RadioTelescopeController( new RadioTelescope( new SpectraCyberSimulatorController( new SpectraCyberSimulator() ) , PLCCCH1 , JohnRudyPark , CalibrationOrientation , 2 ) );
+ RTCMT1 = new RadioTelescopeControllerManagementThread( RTC1 );
}
+
[TestMethod]
public void TestConstructorsAndProperties()
{
+
Assert.AreEqual(RTC0, RTCMT0.RTController);
Assert.AreEqual(RTC1, RTCMT1.RTController);
@@ -67,8 +68,6 @@ public void TestLifecycle()
Assert.AreEqual(true, RTCMT0.Start());
Assert.AreEqual(true, RTCMT1.Start());
- Thread.Sleep(100);
-
Assert.AreEqual(false, RTCMT0.Busy);
Assert.AreEqual(false, RTCMT1.Busy);
@@ -81,22 +80,15 @@ public void TestLifecycle()
Assert.AreEqual(false, RTCMT0.Busy);
Assert.AreEqual(false, RTCMT1.Busy);
}
- //TestCleanup ClassCleanup
+
[TestCleanup]
public void Bringdown() {
- // RTC0.RadioTelescope.PLCDriver.Bring_down();
- // RTC1.RadioTelescope.PLCDriver.Bring_down();
- RTC0 = null;
- RTC1 = null;
+ RTC0.RadioTelescope.PLCDriver.Bring_down();
+ RTC1.RadioTelescope.PLCDriver.Bring_down();
RTCMT0.RequestToKill();
RTCMT1.RequestToKill();
- RTCMT1 = null;
- RTCMT0 = null;
- PLCCCH0 = null;
- PLCCCH1 = null;
- // PLCCCH0.Bring_down();
- Thread.Sleep( 100 );
+ PLCCCH0.Bring_down();
+ PLCCCH1.Bring_down();
}
- //*/
}
}
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/RadioTelescopeControllerTest.cs b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/RadioTelescopeControllerTest.cs
index 82bf86cf..6dd79086 100644
--- a/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/RadioTelescopeControllerTest.cs
+++ b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/RadioTelescopeControllerTest.cs
@@ -3,97 +3,113 @@
using ControlRoomApplication.Constants;
using ControlRoomApplication.Controllers;
using ControlRoomApplication.Entities;
+using ControlRoomApplication.Database;
+using ControlRoomApplication.Simulators.Hardware.WeatherStation;
using System.Threading;
+using System.Threading.Tasks;
+using ControlRoomApplication.Controllers.PLCCommunication.PLCDrivers.MCUManager;
+using ControlRoomApplication.Controllers.SensorNetwork;
+using System.Net;
+using ControlRoomApplication.Controllers.PLCCommunication.PLCDrivers.MCUManager.Enumerations;
-namespace ControlRoomApplicationTest.EntityControllersTests
-{
+namespace ControlRoomApplicationTest.EntityControllersTests {
[TestClass]
- public class RadioTelescopeControllerTest
- {
+ public class RadioTelescopeControllerTest {
private static string ip = PLCConstants.LOCAL_HOST_IP;
private static int port = 8086;
private static RadioTelescopeController TestRadioTelescopeController;
private static TestPLCDriver TestRTPLC;
- [ClassInitialize]
- public static void SetUp(TestContext context)
- {
- //PLCClientCommunicationHandler PLCClientCommHandler = new PLCClientCommunicationHandler(ip, port);
- TestRTPLC = new TestPLCDriver(ip, ip, port, port);
+ private static SensorNetworkServer SensorNetworkServer;
+
+ [TestCleanup]
+ public void testClean() {
+ try {
+ // Make sure all overrides are false
+ TestRadioTelescopeController.overrides.setAzimuthAbsEncoder(false);
+ TestRadioTelescopeController.overrides.setElevationAbsEncoder(false);
+ TestRadioTelescopeController.overrides.setAzimuthMotTemp(false);
+ TestRadioTelescopeController.overrides.setElevationMotTemp(false);
+ TestRadioTelescopeController.overrides.setCounterbalanceAccelerometer(false);
+ TestRadioTelescopeController.overrides.setAzimuthAccelerometer(false);
+ TestRadioTelescopeController.overrides.setElevationAccelerometer(false);
+ TestRadioTelescopeController.overrides.setElProx0Override(false);
+ TestRadioTelescopeController.overrides.setElProx90Override(false);
+
+ TestRadioTelescopeController.RadioTelescope.PLCDriver.publicKillHeartbeatComponent();
+ TestRadioTelescopeController.RadioTelescope.SensorNetworkServer.EndSensorMonitoringRoutine();
+ } catch { }
+ }
+ [TestInitialize]
+ public void testInit() {
+ TestRTPLC = new TestPLCDriver(ip, ip, 15001, 15003, true);
+ // TestRTPLC = new ProductionPLCDriver("192.168.0.70", "192.168.0.50" , 502 , 502 );
SpectraCyberSimulatorController SCSimController = new SpectraCyberSimulatorController(new SpectraCyberSimulator());
Location location = MiscellaneousConstants.JOHN_RUDY_PARK;
+ SensorNetworkServer = new SensorNetworkServer(IPAddress.Parse("127.0.0.1"), 3000, "127.0.0.1", 3001, 500, false);
RadioTelescope TestRT = new RadioTelescope(SCSimController, TestRTPLC, location, new Orientation(0, 0));
+ TestRT.SensorNetworkServer = SensorNetworkServer;
+ //TestRT.SensorNetworkServer.StartSensorMonitoringRoutine();
+ TestRT.WeatherStation = new SimulationWeatherStation(1000);
TestRadioTelescopeController = new RadioTelescopeController(TestRT);
+ // Override motor temperature sensors
+ TestRadioTelescopeController.overrides.overrideAzimuthMotTemp = true;
+ TestRadioTelescopeController.overrides.overrideElevatMotTemp = true;
+ TestRTPLC.setTelescopeType(RadioTelescopeTypeEnum.HARD_STOPS);
TestRTPLC.StartAsyncAcceptingClients();
- //TestRT.PLCClient.ConnectToServer();
+ TestRTPLC.Configure_MCU(.06, .06, 300, 300);
}
[TestMethod]
- public void TestTestCommunication()
- {
+ public void TestTestCommunication() {
var test_result = TestRadioTelescopeController.TestCommunication();
Assert.IsTrue(test_result);
}
[TestMethod]
- public void TestGetCurrentOrientation()
- {
+ public void TestGetCurrentOrientation() {
// Create an Orientation object with an azimuth of 311 and elevation of 42
Orientation Orientation = new Orientation(311.0, 42.0);
// Set the RadioTelescope's CurrentOrientation field
- var response = TestRadioTelescopeController.MoveRadioTelescopeToOrientation(Orientation);
+ MovementResult response = TestRadioTelescopeController.MoveRadioTelescopeToOrientation(Orientation, MovementPriority.Appointment);
// Call the GetCurrentOrientationMethod
Orientation CurrentOrientation = TestRadioTelescopeController.GetCurrentOrientation();
// Ensure the objects are identical
- Assert.IsTrue(response);
- Assert.AreEqual(Orientation.Azimuth, CurrentOrientation.Azimuth,0.001);
+ Assert.AreEqual(response, MovementResult.Success);
+ Assert.AreEqual(Orientation.Azimuth, CurrentOrientation.Azimuth, 0.001);
Assert.AreEqual(Orientation.Elevation, CurrentOrientation.Elevation, 0.001);
Orientation = new Orientation(28.0, 42.0);
// Set the RadioTelescope's CurrentOrientation field
- response = TestRadioTelescopeController.MoveRadioTelescopeToOrientation(Orientation);
+ response = TestRadioTelescopeController.MoveRadioTelescopeToOrientation(Orientation, MovementPriority.Appointment);
// Call the GetCurrentOrientationMethod
CurrentOrientation = TestRadioTelescopeController.GetCurrentOrientation();
- Assert.IsTrue(response);
+ Assert.AreEqual(response, MovementResult.Success);
Assert.AreEqual(Orientation.Azimuth, CurrentOrientation.Azimuth, 0.001);
Assert.AreEqual(Orientation.Elevation, CurrentOrientation.Elevation, 0.001);
Orientation = new Orientation(310.0, 42.0);
// Set the RadioTelescope's CurrentOrientation field
- response = TestRadioTelescopeController.MoveRadioTelescopeToOrientation(Orientation);
+ response = TestRadioTelescopeController.MoveRadioTelescopeToOrientation(Orientation, MovementPriority.Appointment);
// Call the GetCurrentOrientationMethod
CurrentOrientation = TestRadioTelescopeController.GetCurrentOrientation();
// Ensure the objects are identical
- Assert.IsTrue(response);
+ Assert.AreEqual(response, MovementResult.Success);
Assert.AreEqual(Orientation.Azimuth, CurrentOrientation.Azimuth, 0.001);
Assert.AreEqual(Orientation.Elevation, CurrentOrientation.Elevation, 0.001);
}
[TestMethod]
- public void TestGetCurrentLimitSwitchStatuses()
- {
- // Test the limit switch statuses
- var responses = TestRadioTelescopeController.GetCurrentLimitSwitchStatuses();
-
- // Make sure each limit switch is online
- foreach(var response in responses)
- {
- Assert.IsFalse(response);
- }
- }
-
- [TestMethod]
- public void TestGetCurrentSafetyInterlockStatus()
- {
- Thread.Sleep( 1000 );
+ public void TestGetCurrentSafetyInterlockStatus() {
+ Task.Delay(1000).Wait();
//estRTPLC.setSaftyInterlock();
// Test the safety interlock status
@@ -104,65 +120,156 @@ public void TestGetCurrentSafetyInterlockStatus()
}
[TestMethod]
- public void TestCancelCurrentMoveCommand()
- {
+ public void TestCancelCurrentMoveCommand() {
// Test canceling the the current move command
- TestRadioTelescopeController.MoveRadioTelescopeToOrientation(new Orientation(0, 0));
- var response = TestRadioTelescopeController.CancelCurrentMoveCommand();
+ TestRadioTelescopeController.MoveRadioTelescopeToOrientation(new Orientation(0, 0), MovementPriority.Appointment);
+ var response = TestRadioTelescopeController.CancelCurrentMoveCommand(MovementPriority.GeneralStop);
// Make sure it was successful
- Assert.IsTrue(response);
+ Assert.AreEqual(MovementResult.Success, response);
}
[TestMethod]
- public void TestShutdownRadioTelescope()
- {
+ public void TestShutdownRadioTelescope() {
// Call the ShutdownRadioTelescope method
var response = TestRadioTelescopeController.ShutdownRadioTelescope();
Orientation orientation = TestRadioTelescopeController.GetCurrentOrientation();
// The Radio Telescope should now have a CurrentOrientation of (0, -90)
Assert.IsTrue(response);
- Assert.AreEqual(orientation.Azimuth, 0.0 ,0.001);
- Assert.AreEqual(orientation.Elevation, 0.0, 0.001 );
+
+ //Assert.AreEqual( 0.0, orientation.Azimuth, 0.001 );
+ //Assert.AreEqual( 90.0 , orientation.Elevation, 0.001 );
}
[TestMethod]
- public void TestCalibrateRadioTelescope()
- {
+ public void TestThermalCalibrateRadioTelescope() {
+ Orientation before = TestRadioTelescopeController.GetCurrentOrientation();
+
// Call the CalibrateRadioTelescope method
- var response = TestRadioTelescopeController.CalibrateRadioTelescope();
+ var response = TestRadioTelescopeController.ThermalCalibrateRadioTelescope(MovementPriority.Appointment);
+ // this var response is going to be null because there is no reading. It means that the
+ // telescope isn't calibrated. At this time, all we care about is the movement
- // The Radio Telescope should now have a CurrentOrienation of (0,0)
- Assert.IsTrue(response);
- Assert.AreEqual(TestRadioTelescopeController.RadioTelescope.CurrentOrientation.Azimuth, 0.0);
- Assert.AreEqual(TestRadioTelescopeController.RadioTelescope.CurrentOrientation.Elevation, 0.0);
+ // The Radio Telescope should now have a CurrentOrienation of what it had before the call
+ Assert.AreEqual(TestRadioTelescopeController.RadioTelescope.CurrentOrientation.Azimuth, before.Azimuth);
+ Assert.AreEqual(TestRadioTelescopeController.RadioTelescope.CurrentOrientation.Elevation, before.Elevation);
}
[TestMethod]
- public void TestMoveRadioTelescope()
+ public void TestMoveRadioTelescope_HardStops()
{
+ // Set the Telescope Type to HARD STOPS
+ TestRTPLC.setTelescopeType(RadioTelescopeTypeEnum.HARD_STOPS);
+
// Create an Orientation object with an azimuth of 311 and elevation of 42
Orientation Orientation = new Orientation(311.0, 42.0);
// Set the RadioTelescope's CurrentOrientation field
- var response = TestRadioTelescopeController.MoveRadioTelescopeToOrientation(Orientation);
+ MovementResult response = TestRadioTelescopeController.MoveRadioTelescopeToOrientation(Orientation, MovementPriority.Appointment);
// Call the GetCurrentOrientationMethod
Orientation CurrentOrientation = TestRadioTelescopeController.GetCurrentOrientation();
// Ensure the objects are identical
- Assert.IsTrue(response);
- Assert.AreEqual(Orientation.Azimuth, CurrentOrientation.Azimuth,0.001);
- Assert.AreEqual(Orientation.Elevation, CurrentOrientation.Elevation,0.001);
+ Assert.AreEqual(response, MovementResult.Success);
+ Assert.AreEqual(Orientation.Azimuth, CurrentOrientation.Azimuth, 0.001);
+ Assert.AreEqual(Orientation.Elevation, CurrentOrientation.Elevation, 0.001);
+ }
+
+ [TestMethod]
+ public void TestMoveRadioTelescope_SlipRing_311degrees()
+ {
+ // Set the Telescope Type to SLIP RING
+ TestRTPLC.setTelescopeType(RadioTelescopeTypeEnum.SLIP_RING);
+
+ // Create an Orientation object with an azimuth of 311 and elevation of 0
+ Orientation TargetOrientation = new Orientation(311.0, 0);
+
+ // Set the RadioTelescope's CurrentOrientation field
+ MovementResult response = TestRadioTelescopeController.MoveRadioTelescopeToOrientation(TargetOrientation, MovementPriority.Appointment);
+
+ // Call the GetCurrentOrientationMethod
+ Orientation CurrentOrientation = TestRadioTelescopeController.GetCurrentOrientation();
+
+ // Ensure the objects are identical
+ Assert.AreEqual(response, MovementResult.Success);
+ Assert.AreEqual(TargetOrientation.Azimuth, CurrentOrientation.Azimuth, 0.001);
+ Assert.AreEqual(TargetOrientation.Elevation, CurrentOrientation.Elevation, 0.001);
+ }
+
+ [TestMethod]
+ public void TestMoveRadioTelescope_SlipRing_359degrees()
+ {
+ // Set the Telescope Type to SLIP RING
+ TestRTPLC.setTelescopeType(RadioTelescopeTypeEnum.SLIP_RING);
+
+ // Create an Orientation object with an azimuth of 311 and elevation of 0
+ Orientation TargetOrientation = new Orientation(359.0, 0);
+
+ // Set the RadioTelescope's CurrentOrientation field
+ MovementResult response = TestRadioTelescopeController.MoveRadioTelescopeToOrientation(TargetOrientation, MovementPriority.Appointment);
+
+ // Call the GetCurrentOrientationMethod
+ Orientation CurrentOrientation = TestRadioTelescopeController.GetCurrentOrientation();
+
+ // Ensure the objects are identical
+ Assert.AreEqual(response, MovementResult.Success);
+ Assert.AreEqual(TargetOrientation.Azimuth, CurrentOrientation.Azimuth, 0.001);
+ Assert.AreEqual(TargetOrientation.Elevation, CurrentOrientation.Elevation, 0.001);
+ }
+
+ [TestMethod]
+ public void TestMoveRadioTelescope_SlipRing_MoveFrom350To90()
+ {
+ // Set the Telescope Type to SLIP RING
+ TestRTPLC.setTelescopeType(RadioTelescopeTypeEnum.SLIP_RING);
+
+ // Initial movement from 0 to 350
+ Orientation InitialOrientation = new Orientation(350, 0);
+ TestRadioTelescopeController.MoveRadioTelescopeToOrientation(InitialOrientation, MovementPriority.Appointment);
+
+ // Move from 350 to 90
+ Orientation TargetOrientation = new Orientation(90, 0);
+ MovementResult response = TestRadioTelescopeController.MoveRadioTelescopeToOrientation(TargetOrientation, MovementPriority.Appointment);
+
+ // Call the GetCurrentOrientationMethod
+ Orientation CurrentOrientation = TestRadioTelescopeController.GetCurrentOrientation();
+
+ // Ensure the objects are identical
+ Assert.AreEqual(response, MovementResult.Success);
+ Assert.AreEqual(TargetOrientation.Azimuth, CurrentOrientation.Azimuth, 0.001);
+ Assert.AreEqual(TargetOrientation.Elevation, CurrentOrientation.Elevation, 0.001);
}
[TestMethod]
- public void test_conversions()
+ public void TestMoveRadioTelescope_SlipRing_MoveFrom90To350()
{
+ // Set the Telescope Type to SLIP RING
+ TestRTPLC.setTelescopeType(RadioTelescopeTypeEnum.SLIP_RING);
+
+ // Initial movement from 0 to 90
+ Orientation InitialOrientation = new Orientation(90, 0);
+ TestRadioTelescopeController.MoveRadioTelescopeToOrientation(InitialOrientation, MovementPriority.Appointment);
+
+ // Move from 90 to 350
+ Orientation TargetOrientation = new Orientation(350, 0);
+ MovementResult response = TestRadioTelescopeController.MoveRadioTelescopeToOrientation(TargetOrientation, MovementPriority.Appointment);
+
+ // Call the GetCurrentOrientationMethod
+ Orientation CurrentOrientation = TestRadioTelescopeController.GetCurrentOrientation();
+
+ // Ensure the objects are identical
+ Assert.AreEqual(response, MovementResult.Success);
+ Assert.AreEqual(TargetOrientation.Azimuth, CurrentOrientation.Azimuth, 0.001);
+ Assert.AreEqual(TargetOrientation.Elevation, CurrentOrientation.Elevation, 0.001);
+ }
+
+ [TestMethod]
+ public void test_conversions() {
Random random = new Random();
double degaz = 83.33, degel = 43.34;
- int az= ConversionHelper.DegreesToSteps(degaz, MotorConstants.GEARING_RATIO_AZIMUTH);
+ int az = ConversionHelper.DegreesToSteps(degaz, MotorConstants.GEARING_RATIO_AZIMUTH);
double testaz = ConversionHelper.StepsToDegrees(az, MotorConstants.GEARING_RATIO_AZIMUTH);
Assert.AreEqual(degaz, testaz, 0.001);
@@ -170,9 +277,8 @@ public void test_conversions()
double testel = ConversionHelper.StepsToDegrees(el, MotorConstants.GEARING_RATIO_ELEVATION);
Assert.AreEqual(degel, testel, 0.001);
- for (int i = 0; i < 360; i++)
- {
- double val=i+ random.NextDouble();
+ for (int i = 0; i < 360; i++) {
+ double val = i + random.NextDouble();
az = ConversionHelper.DegreesToSteps(val, MotorConstants.GEARING_RATIO_AZIMUTH);
testaz = ConversionHelper.StepsToDegrees(az, MotorConstants.GEARING_RATIO_AZIMUTH);
Assert.AreEqual(val, testaz, 0.001);
@@ -181,55 +287,904 @@ public void test_conversions()
testel = ConversionHelper.StepsToDegrees(el, MotorConstants.GEARING_RATIO_ELEVATION);
Assert.AreEqual(val, testel, 0.001);
}
+
+ double RPM = .5;
+ int STEPSperSECOND = 83_333;
+
+ int xpx = ConversionHelper.RPMToSPS(RPM, MotorConstants.GEARING_RATIO_AZIMUTH);
+ Assert.AreEqual(STEPSperSECOND, xpx);
+
+ double RPMOUT = ConversionHelper.SPSToRPM(xpx, MotorConstants.GEARING_RATIO_AZIMUTH);
+ Assert.AreEqual(RPM, RPMOUT, 0.01);
+
+ double dps = 3;
+ xpx = ConversionHelper.DPSToSPS(dps, MotorConstants.GEARING_RATIO_AZIMUTH);
+ Assert.AreEqual(STEPSperSECOND, xpx);
+
+ double dpsOUT = ConversionHelper.SPSToDPS(xpx, MotorConstants.GEARING_RATIO_AZIMUTH);
+ Assert.AreEqual(dps, dpsOUT, 0.01);
+
+
}
[TestMethod]
- public void test_orientation_change()
+ public void test_MCU_Time_Estimate() {
+ int vel = 170_000, dist = 10_000_000;
+ int time = MCUManager.EstimateMovementTime(vel, dist);
+ Assert.AreEqual(61800, time);
+ }
+
+ [TestMethod]
+ public void testOrientationChange_100_100Degrees()
{
- Random random = new Random();
-
- Orientation current_orientation2;
- current_orientation2 = TestRadioTelescopeController.RadioTelescope.PLCDriver.read_Position();
- Orientation current_orientation = current_orientation2;
+ // Acquire current orientation
+ Orientation currOrientation;
+ currOrientation = TestRadioTelescopeController.RadioTelescope.PLCDriver.GetMotorEncoderPosition();
+
+ // Calculate motor steps from current orientation
+ int currStepsAz, currStepsEl;
+ currStepsAz = ConversionHelper.DegreesToSteps(currOrientation.Azimuth, MotorConstants.GEARING_RATIO_AZIMUTH);
+ currStepsEl = ConversionHelper.DegreesToSteps(currOrientation.Elevation, MotorConstants.GEARING_RATIO_ELEVATION);
+
+ // Set target orientation on both Azimuth and Elevation, respectively
+ Orientation expectedOrientation = new Orientation(100, 100);
+
+ // Calculate motor steps necessary for movement
+ int posTransAz, posTransEl;
+ posTransAz = ConversionHelper.DegreesToSteps(expectedOrientation.Azimuth - currOrientation.Azimuth, MotorConstants.GEARING_RATIO_AZIMUTH);
+ posTransEl = ConversionHelper.DegreesToSteps(expectedOrientation.Elevation - currOrientation.Elevation, MotorConstants.GEARING_RATIO_ELEVATION);
+
+ // Move telescope
+ TestRadioTelescopeController.RadioTelescope.PLCDriver.RelativeMove(100_000, 100_000, posTransAz, posTransEl, expectedOrientation);
+
+ // Create result orientation
+ Orientation resultOrientation = TestRadioTelescopeController.RadioTelescope.PLCDriver.GetMotorEncoderPosition();
+
+ // Assert expected and result are identical
+ Assert.AreEqual(expectedOrientation, resultOrientation);
+ }
+
+ [TestMethod]
+ public void testOrientationChange_0_0Degrees()
+ {
+ // Acquire current orientation
+ Orientation currOrientation;
+ currOrientation = TestRadioTelescopeController.RadioTelescope.PLCDriver.GetMotorEncoderPosition();
+
+ // Calculate motor steps from current orientation
+ int currStepsAz, currStepsEl;
+ currStepsAz = ConversionHelper.DegreesToSteps(currOrientation.Azimuth, MotorConstants.GEARING_RATIO_AZIMUTH);
+ currStepsEl = ConversionHelper.DegreesToSteps(currOrientation.Elevation, MotorConstants.GEARING_RATIO_ELEVATION);
+
+ // Set target orientation on both Azimuth and Elevation, respectively
+ Orientation expectedOrientation = new Orientation(0, 0);
+
+ // Calculate motor steps necessary for movement
+ int posTransAz, posTransEl;
+ posTransAz = ConversionHelper.DegreesToSteps(expectedOrientation.Azimuth - currOrientation.Azimuth, MotorConstants.GEARING_RATIO_AZIMUTH);
+ posTransEl = ConversionHelper.DegreesToSteps(expectedOrientation.Elevation - currOrientation.Elevation, MotorConstants.GEARING_RATIO_ELEVATION);
+
+ // Move telescope
+ TestRadioTelescopeController.RadioTelescope.PLCDriver.RelativeMove(100_000, 100_000, posTransAz, posTransEl, expectedOrientation);
+
+ // Create result orientation
+ Orientation resultOrientation = TestRadioTelescopeController.RadioTelescope.PLCDriver.GetMotorEncoderPosition();
+
+ // Assert expected and result are identical
+ Assert.AreEqual(expectedOrientation, resultOrientation);
+ }
+
+ [TestMethod]
+ public void testOrientationChange_360_210Degrees()
+ {
+ // Set the Telescope Type to SLIP RING
+ TestRTPLC.setTelescopeType(RadioTelescopeTypeEnum.HARD_STOPS);
+
+ // Acquire current orientation
+ Orientation currOrientation;
+ currOrientation = TestRadioTelescopeController.RadioTelescope.PLCDriver.GetMotorEncoderPosition();
+
+ // Calculate motor steps from current orientation
+ int currStepsAz, currStepsEl;
+ currStepsAz = ConversionHelper.DegreesToSteps(currOrientation.Azimuth, MotorConstants.GEARING_RATIO_AZIMUTH);
+ currStepsEl = ConversionHelper.DegreesToSteps(currOrientation.Elevation, MotorConstants.GEARING_RATIO_ELEVATION);
+
+ // Set target orientation on both Azimuth and Elevation, respectively
+ Orientation expectedOrientation = new Orientation(360, 210);
+
+ // Calculate motor steps necessary for movement
+ int posTransAz, posTransEl;
+ posTransAz = ConversionHelper.DegreesToSteps(expectedOrientation.Azimuth - currOrientation.Azimuth, MotorConstants.GEARING_RATIO_AZIMUTH);
+ posTransEl = ConversionHelper.DegreesToSteps(expectedOrientation.Elevation - currOrientation.Elevation, MotorConstants.GEARING_RATIO_ELEVATION);
+
+ // Move telescope
+ TestRadioTelescopeController.RadioTelescope.PLCDriver.RelativeMove(100_000, 100_000, posTransAz, posTransEl, expectedOrientation);
+
+ // Create result orientation
+ Orientation resultOrientation = TestRadioTelescopeController.RadioTelescope.PLCDriver.GetMotorEncoderPosition();
+
+ // Assert expected and result are identical
+ Assert.AreEqual(expectedOrientation.Azimuth, resultOrientation.Azimuth, 0.001);
+ Assert.AreEqual(expectedOrientation.Elevation, resultOrientation.Elevation, 0.001);
+ }
+
+ [TestMethod]
+ public void test_temperature_check()
+ {
+ // make sure neither override is set
+ DatabaseOperations.SetOverrideForSensor(SensorItemEnum.AZIMUTH_MOTOR, false);
+ DatabaseOperations.SetOverrideForSensor(SensorItemEnum.ELEVATION_MOTOR, false);
+
+ // Enable motor temperature sensors
+ TestRadioTelescopeController.overrides.overrideAzimuthMotTemp = false;
+ TestRadioTelescopeController.overrides.overrideElevatMotTemp = false;
+
+ /** Azimuth tests **/
+ Temperature az = new Temperature(); az.location_ID = (int)SensorLocationEnum.AZ_MOTOR;
+
+ // Stable
+ az.temp = 100;
+ Assert.IsTrue(TestRadioTelescopeController.checkTemp(az, true));
+
+ // Stable
+ az.temp = 50;
+ Assert.IsTrue(TestRadioTelescopeController.checkTemp(az, true));
+
+ // Overheating
+ az.temp = 151;
+ Assert.IsFalse(TestRadioTelescopeController.checkTemp(az, true));
+
+ // Overheating
+ az.temp = 151;
+ Assert.IsFalse(TestRadioTelescopeController.checkTemp(az, true));
+
+ // Too cold
+ az.temp = -1;
+ Assert.IsFalse(TestRadioTelescopeController.checkTemp(az, true));
+
+
+ /** Elevation tests **/
+ Temperature el = new Temperature(); el.location_ID = (int)SensorLocationEnum.EL_MOTOR;
+
+ // Stable
+ el.temp = 100;
+ Assert.IsTrue(TestRadioTelescopeController.checkTemp(el, true));
+
+ // Stable
+ el.temp = 50;
+ Assert.IsTrue(TestRadioTelescopeController.checkTemp(el, true));
+
+ // Overheating
+ el.temp = 151;
+ Assert.IsFalse(TestRadioTelescopeController.checkTemp(el, true));
+
+ // Too cold
+ el.temp = -1;
+ Assert.IsFalse(TestRadioTelescopeController.checkTemp(el, true));
+ }
+
+ [TestMethod]
+ public void test_temperature_overrides()
+ {
+ // make sure both overrides are set
+ TestRadioTelescopeController.overrides.overrideAzimuthMotTemp = true;
+ TestRadioTelescopeController.overrides.overrideElevatMotTemp = true;
+
+ /** Azimuth temperatures **/
+ Temperature az = new Temperature(); az.location_ID = (int)SensorLocationEnum.AZ_MOTOR;
+
+ // Stable
+ az.temp = 50;
+ Assert.IsTrue(TestRadioTelescopeController.checkTemp(az, true));
+
+ // Stable
+ az.temp = 150;
+ Assert.IsTrue(TestRadioTelescopeController.checkTemp(az, true));
+
+ // Overheating
+ az.temp = 151;
+ Assert.IsTrue(TestRadioTelescopeController.checkTemp(az, true));
+
+ // To cold
+ az.temp = 49;
+ Assert.IsTrue(TestRadioTelescopeController.checkTemp(az, true));
+
+
+ /** Elevation temperatures **/
+ Temperature el = new Temperature(); el.location_ID = (int)SensorLocationEnum.EL_MOTOR;
+
+ // Stable
+ el.temp = 50;
+ Assert.IsTrue(TestRadioTelescopeController.checkTemp(el, true));
+
+ // Stable
+ el.temp = 150;
+ Assert.IsTrue(TestRadioTelescopeController.checkTemp(el, true));
+
+ // Overheating
+ el.temp = 151;
+ Assert.IsTrue(TestRadioTelescopeController.checkTemp(el, true));
+
+ // To cold
+ el.temp = 49;
+ Assert.IsTrue(TestRadioTelescopeController.checkTemp(el, true));
+ }
+
+ [TestMethod]
+ public void test_plc_overrides()
+ {
+ // Default override settings (no override)
+ Assert.IsTrue(0 == (int)TestRadioTelescopeController.RadioTelescope.PLCDriver.getregvalue((ushort)PLC_modbus_server_register_mapping.AZ_0_LIMIT));
+ Assert.IsTrue(0 == (int)TestRadioTelescopeController.RadioTelescope.PLCDriver.getregvalue((ushort)PLC_modbus_server_register_mapping.AZ_375_LIMIT));
+ Assert.IsTrue(0 == (int)TestRadioTelescopeController.RadioTelescope.PLCDriver.getregvalue((ushort)PLC_modbus_server_register_mapping.EL_10_LIMIT));
+ Assert.IsTrue(0 == (int)TestRadioTelescopeController.RadioTelescope.PLCDriver.getregvalue((ushort)PLC_modbus_server_register_mapping.EL_90_LIMIT));
+ Assert.IsTrue(0 == (int)TestRadioTelescopeController.RadioTelescope.PLCDriver.getregvalue((ushort)PLC_modbus_server_register_mapping.GATE_OVERRIDE));
+
+ // Flip switches
+ TestRadioTelescopeController.RadioTelescope.PLCDriver.setregvalue((ushort)PLC_modbus_server_register_mapping.AZ_0_LIMIT, 1);
+ TestRadioTelescopeController.RadioTelescope.PLCDriver.setregvalue((ushort)PLC_modbus_server_register_mapping.AZ_375_LIMIT, 1);
+ TestRadioTelescopeController.RadioTelescope.PLCDriver.setregvalue((ushort)PLC_modbus_server_register_mapping.EL_10_LIMIT, 1);
+ TestRadioTelescopeController.RadioTelescope.PLCDriver.setregvalue((ushort)PLC_modbus_server_register_mapping.EL_90_LIMIT, 1);
+ TestRadioTelescopeController.RadioTelescope.PLCDriver.setregvalue((ushort)PLC_modbus_server_register_mapping.GATE_OVERRIDE, 1);
+
+ // Now overriding
+ Assert.IsTrue(1 == (int)TestRadioTelescopeController.RadioTelescope.PLCDriver.getregvalue((ushort)PLC_modbus_server_register_mapping.AZ_0_LIMIT));
+ Assert.IsTrue(1 == (int)TestRadioTelescopeController.RadioTelescope.PLCDriver.getregvalue((ushort)PLC_modbus_server_register_mapping.AZ_375_LIMIT));
+ Assert.IsTrue(1 == (int)TestRadioTelescopeController.RadioTelescope.PLCDriver.getregvalue((ushort)PLC_modbus_server_register_mapping.EL_10_LIMIT));
+ Assert.IsTrue(1 == (int)TestRadioTelescopeController.RadioTelescope.PLCDriver.getregvalue((ushort)PLC_modbus_server_register_mapping.EL_90_LIMIT));
+ Assert.IsTrue(1 == (int)TestRadioTelescopeController.RadioTelescope.PLCDriver.getregvalue((ushort)PLC_modbus_server_register_mapping.GATE_OVERRIDE));
+ }
+
+ [TestMethod]
+ public void TestHomeTelescope_BothAbsolutePositionsOK_Success()
+ {
+ MovementResult result = TestRadioTelescopeController.HomeTelescope(MovementPriority.Manual);
+
+ Assert.AreEqual(MovementResult.Success, result);
+ }
+
+ [TestMethod]
+ public void TestHomeTelescope_ElevationAbsoluteEncoderOff_IncorrectPosition()
+ {
+ SensorNetworkServer.CurrentAbsoluteOrientation.Elevation = 1;
+
+ MovementResult result = TestRadioTelescopeController.HomeTelescope(MovementPriority.Manual);
+
+ Assert.AreEqual(MovementResult.IncorrectPosition, result);
+ }
+
+ [TestMethod]
+ public void TestHomeTelescope_AzimuthAbsoluteEncoderOff_IncorrectPosition()
+ {
+ SensorNetworkServer.CurrentAbsoluteOrientation.Azimuth = 1;
+
+ MovementResult result = TestRadioTelescopeController.HomeTelescope(MovementPriority.Manual);
+
+ Assert.AreEqual(MovementResult.IncorrectPosition, result);
+ }
+
+ [TestMethod]
+ public void TestHomeTelescope_BothAbsoluteEncodersOff_IncorrectPosition()
+ {
+ SensorNetworkServer.CurrentAbsoluteOrientation.Azimuth = 1;
+ SensorNetworkServer.CurrentAbsoluteOrientation.Elevation = 1;
+
+ MovementResult result = TestRadioTelescopeController.HomeTelescope(MovementPriority.Manual);
+
+ Assert.AreEqual(MovementResult.IncorrectPosition, result);
+ }
+
+ [TestMethod]
+ public void TestHomeTelescope_AzimuthAbsoluteEncoderOffButOverridden_Success()
+ {
+ SensorNetworkServer.CurrentAbsoluteOrientation.Azimuth = 1;
+ TestRadioTelescopeController.overrides.setAzimuthAbsEncoder(true);
+
+ MovementResult result = TestRadioTelescopeController.HomeTelescope(MovementPriority.Manual);
+
+ Assert.AreEqual(MovementResult.Success, result);
+ }
+
+ [TestMethod]
+ public void TestHomeTelescope_ElevationAbsoluteEncoderOffButOverridden_Success()
+ {
+ SensorNetworkServer.CurrentAbsoluteOrientation.Elevation = 1;
+ TestRadioTelescopeController.overrides.setElevationAbsEncoder(true);
+
+ MovementResult result = TestRadioTelescopeController.HomeTelescope(MovementPriority.Manual);
+
+ Assert.AreEqual(MovementResult.Success, result);
+ }
+
+ [TestMethod]
+ public void TestHomeTelescope_BothAbsoluteEncodersOffButOverridden_Success()
+ {
+ SensorNetworkServer.CurrentAbsoluteOrientation.Elevation = 1;
+ SensorNetworkServer.CurrentAbsoluteOrientation.Azimuth = 1;
+ TestRadioTelescopeController.overrides.setElevationAbsEncoder(true);
+ TestRadioTelescopeController.overrides.setAzimuthAbsEncoder(true);
+
+ MovementResult result = TestRadioTelescopeController.HomeTelescope(MovementPriority.Manual);
+
+ Assert.AreEqual(MovementResult.Success, result);
+ }
+
+ [TestMethod]
+ public void TestHomeTelescope_AzimuthEncoderOKAndOverridden_Success()
+ {
+ TestRadioTelescopeController.overrides.setAzimuthAbsEncoder(true);
+
+ MovementResult result = TestRadioTelescopeController.HomeTelescope(MovementPriority.Manual);
+
+ Assert.AreEqual(MovementResult.Success, result);
+ }
+
+ [TestMethod]
+ public void TestHomeTelescope_ElevationEncoderOKAndOverridden_Success()
+ {
+ TestRadioTelescopeController.overrides.setElevationAbsEncoder(true);
+
+ MovementResult result = TestRadioTelescopeController.HomeTelescope(MovementPriority.Manual);
+
+ Assert.AreEqual(MovementResult.Success, result);
+ }
+
+ [TestMethod]
+ public void TestHomeTelescope_BothEncodersOKAndOverridden_Success()
+ {
+ TestRadioTelescopeController.overrides.setElevationAbsEncoder(true);
+ TestRadioTelescopeController.overrides.setAzimuthAbsEncoder(true);
+
+ MovementResult result = TestRadioTelescopeController.HomeTelescope(MovementPriority.Manual);
+
+ Assert.AreEqual(MovementResult.Success, result);
+ }
+
+ [TestMethod]
+ public void TestHomeTelescope_SensorDataUnsafe_SensorsNotSafe()
+ {
+ SensorNetworkServer.CurrentElevationMotorTemp[0].temp = 3000;
+ SensorNetworkServer.CurrentElevationMotorTemp[0].location_ID = (int)SensorLocationEnum.EL_MOTOR;
+ TestRadioTelescopeController.overrides.setElevationMotTemp(false);
+
+ Thread.Sleep(2000);
+
+ MovementResult result = TestRadioTelescopeController.HomeTelescope(MovementPriority.Manual);
+
+ Assert.AreEqual(MovementResult.SensorsNotSafe, result);
+ }
- int positionTranslationAZ, positionTranslationEL, current_stepsAZ, current_stepsEL;
- current_stepsAZ = ConversionHelper.DegreesToSteps(current_orientation.Azimuth, MotorConstants.GEARING_RATIO_AZIMUTH);
- current_stepsEL = ConversionHelper.DegreesToSteps(current_orientation.Elevation, MotorConstants.GEARING_RATIO_ELEVATION);
- for (int i = 0; i < 1500; i++)
+ [TestMethod]
+ public void TestHomeTelescope_ContainsFinalOffset_SetsFinalOffset()
+ {
+ Orientation expectedOrientation = new Orientation(20, 20);
+
+ TestRadioTelescopeController.RadioTelescope.CalibrationOrientation = expectedOrientation;
+
+ MovementResult result = TestRadioTelescopeController.HomeTelescope(MovementPriority.Manual);
+
+ Orientation resultMotorEncoderOrientation = TestRadioTelescopeController.GetCurrentOrientation();
+ Orientation resultAbsoluteEncoderOrientation = TestRadioTelescopeController.GetAbsoluteOrientation();
+
+ Assert.AreEqual(MovementResult.Success, result);
+ Assert.IsTrue(expectedOrientation.Equals(resultMotorEncoderOrientation));
+ Assert.IsTrue(expectedOrientation.Equals(resultAbsoluteEncoderOrientation));
+ }
+
+ [TestMethod]
+ public void TestHomeTelescope_FinalOffsetAboveAz360_NormalizesAzOffset()
+ {
+ Orientation expectedOrientation = new Orientation(0.5, 20);
+
+ TestRadioTelescopeController.RadioTelescope.CalibrationOrientation = new Orientation(360.5, 20); ;
+
+ MovementResult result = TestRadioTelescopeController.HomeTelescope(MovementPriority.Manual);
+
+ Orientation resultMotorEncoderOrientation = TestRadioTelescopeController.GetCurrentOrientation();
+ Orientation resultAbsoluteEncoderOrientation = TestRadioTelescopeController.GetAbsoluteOrientation();
+
+ Assert.AreEqual(MovementResult.Success, result);
+ Assert.IsTrue(expectedOrientation.Equals(resultMotorEncoderOrientation));
+ Assert.IsTrue(expectedOrientation.Equals(resultAbsoluteEncoderOrientation));
+ }
+
+ [TestMethod]
+ public void TestHomeTelescope_FinalOffsetBelowAz0_NormalizesAzOffset()
+ {
+ Orientation expectedOrientation = new Orientation(359.5, 20);
+
+ TestRadioTelescopeController.RadioTelescope.CalibrationOrientation = new Orientation(-0.5, 20); ;
+
+ MovementResult result = TestRadioTelescopeController.HomeTelescope(MovementPriority.Manual);
+
+ Orientation resultMotorEncoderOrientation = TestRadioTelescopeController.GetCurrentOrientation();
+ Orientation resultAbsoluteEncoderOrientation = TestRadioTelescopeController.GetAbsoluteOrientation();
+
+ Assert.AreEqual(MovementResult.Success, result);
+ Assert.IsTrue(expectedOrientation.Equals(resultMotorEncoderOrientation));
+ Assert.IsTrue(expectedOrientation.Equals(resultAbsoluteEncoderOrientation));
+ }
+
+ [TestMethod]
+ public void TestSnowDump_AllStatusesOK_Success()
+ {
+ MovementResult result = TestRadioTelescopeController.SnowDump(MovementPriority.Manual);
+
+ Assert.AreEqual(MovementResult.Success, result);
+ }
+
+ [TestMethod]
+ public void TestSnowDump_SensorDataUnsafe_SensorsNotSafe()
+ {
+ SensorNetworkServer.CurrentElevationMotorTemp[0].temp = 3000;
+ SensorNetworkServer.CurrentElevationMotorTemp[0].location_ID = (int)SensorLocationEnum.EL_MOTOR;
+ TestRadioTelescopeController.overrides.setElevationMotTemp(false);
+
+ Thread.Sleep(2000);
+
+ MovementResult result = TestRadioTelescopeController.SnowDump(MovementPriority.Manual);
+
+ Assert.AreEqual(MovementResult.SensorsNotSafe, result);
+ }
+
+ [TestMethod]
+ public void TestSnowDump_TriesSnowDumpWithAnotherCommandRunning_AlreadyMoving()
+ {
+ MovementResult result0 = MovementResult.None;
+ MovementResult result1 = MovementResult.None;
+ MovementPriority priority = MovementPriority.Manual;
+
+ // This is running two commands at the same time. One of them should succeed, while
+ // the other is rejected
+
+ Thread t0 = new Thread(() =>
{
- Orientation target_orientation = new Orientation(random.NextDouble() * 360, random.NextDouble() * 360);
- positionTranslationAZ = ConversionHelper.DegreesToSteps((target_orientation.Azimuth - current_orientation.Azimuth), MotorConstants.GEARING_RATIO_AZIMUTH);
- positionTranslationEL = ConversionHelper.DegreesToSteps((target_orientation.Elevation - current_orientation.Elevation), MotorConstants.GEARING_RATIO_ELEVATION);
+ result0 = TestRadioTelescopeController.SnowDump(priority);
+ });
+ Thread t1 = new Thread(() =>
+ {
+ result1 = TestRadioTelescopeController.SnowDump(priority);
+ });
- Console.WriteLine("AZ_01 {0,16} EL_01 {1,16}", current_stepsAZ, current_stepsEL);
- current_stepsAZ = current_stepsAZ + positionTranslationAZ;
- current_stepsEL = current_stepsEL + positionTranslationEL;
+ t0.Start();
+ t1.Start();
- current_orientation = new Orientation(ConversionHelper.StepsToDegrees(current_stepsAZ, MotorConstants.GEARING_RATIO_AZIMUTH), ConversionHelper.StepsToDegrees(current_stepsEL, MotorConstants.GEARING_RATIO_ELEVATION));
+ t0.Join();
+ t1.Join();
- Assert.AreEqual(target_orientation.Azimuth, current_orientation.Azimuth, 0.001);
- Assert.AreEqual(target_orientation.Elevation, current_orientation.Elevation, 0.001);
- Console.WriteLine("AZ_finni0 {0,10} EL_finni0 {1,10}", current_stepsAZ, current_stepsEL);
- // current_orientation = new Orientation(ConversionHelper.StepsToDegrees(current_stepsAZ + positionTranslationAZ, MotorConstants.GEARING_RATIO_AZIMUTH), ConversionHelper.StepsToDegrees(current_stepsEL + positionTranslationEL, MotorConstants.GEARING_RATIO_ELEVATION));
- //Console.WriteLine(current_orientation.Elevation + " "+ target_orientation.Elevation);
- // Console.WriteLine("AZ_step1 {0,10} EL_step1 {1,10}", positionTranslationAZ, positionTranslationEL);
- TestRadioTelescopeController.RadioTelescope.PLCDriver.relative_move(50, 50, positionTranslationAZ, positionTranslationEL);
+ Assert.IsTrue(result0 == MovementResult.Success || result1 == MovementResult.Success);
+ Assert.IsTrue(result0 == MovementResult.AlreadyMoving || result1 == MovementResult.AlreadyMoving);
+ }
- current_orientation2 = TestRadioTelescopeController.RadioTelescope.PLCDriver.read_Position();
+ [TestMethod]
+ public void TestFullElevationMove_AllStatusesOK_Success()
+ {
+ MovementResult result = TestRadioTelescopeController.FullElevationMove(MovementPriority.Manual);
- Assert.AreEqual(target_orientation.Azimuth, current_orientation2.Azimuth, 0.001);
- Assert.AreEqual(target_orientation.Elevation, current_orientation2.Elevation, 0.001);
- }
+ Assert.AreEqual(MovementResult.Success, result);
+ }
+
+ [TestMethod]
+ public void TestFullElevationMove_SensorDataUnsafe_SensorsNotSafe()
+ {
+ TestRadioTelescopeController.overrides.setElevationMotTemp(false);
+ SensorNetworkServer.CurrentElevationMotorTemp[0].temp = 3000;
+ SensorNetworkServer.CurrentElevationMotorTemp[0].location_ID = (int)SensorLocationEnum.EL_MOTOR;
+
+ Thread.Sleep(2000);
+
+ MovementResult result = TestRadioTelescopeController.FullElevationMove(MovementPriority.Manual);
+
+ Assert.AreEqual(MovementResult.SensorsNotSafe, result);
+ }
+
+ [TestMethod]
+ public void TestFullElevationMove_TriesFullElevationMoveWithAnotherCommandRunning_AlreadyMoving()
+ {
+ MovementResult result0 = MovementResult.None;
+ MovementResult result1 = MovementResult.None;
+ MovementPriority priority = MovementPriority.Manual;
+
+ // This is running two commands at the same time. One of them should succeed, while
+ // the other is rejected
+
+ Thread t0 = new Thread(() =>
+ {
+ result0 = TestRadioTelescopeController.FullElevationMove(priority);
+ });
+
+ Thread t1 = new Thread(() =>
+ {
+ result1 = TestRadioTelescopeController.FullElevationMove(priority);
+ });
+
+ t0.Start();
+ t1.Start();
+
+ t0.Join();
+ t1.Join();
+
+ Assert.IsTrue(result0 == MovementResult.Success || result1 == MovementResult.Success);
+ Assert.IsTrue(result0 == MovementResult.AlreadyMoving || result1 == MovementResult.AlreadyMoving);
+ }
+
+ [TestMethod]
+ public void TestMoveRadioTelescopeToCoordinate_AllStatusesOK_Success()
+ {
+ Coordinate c = new Coordinate();
+
+ MovementResult result = TestRadioTelescopeController.MoveRadioTelescopeToCoordinate(c, MovementPriority.Manual);
+
+ Assert.AreEqual(MovementResult.Success, result);
+ }
+
+ [TestMethod]
+ public void TestMoveRadioTelescopeToCoordinate_SensorDataUnsafe_SensorsNotSafe()
+ {
+ TestRadioTelescopeController.overrides.setElevationMotTemp(false);
+ SensorNetworkServer.CurrentElevationMotorTemp[0].temp = 3000;
+ SensorNetworkServer.CurrentElevationMotorTemp[0].location_ID = (int)SensorLocationEnum.EL_MOTOR;
+
+ Coordinate c = new Coordinate();
+
+ Thread.Sleep(2000);
+
+ MovementResult result = TestRadioTelescopeController.MoveRadioTelescopeToCoordinate(c, MovementPriority.Manual);
+
+ Assert.AreEqual(MovementResult.SensorsNotSafe, result);
+ }
+
+ [TestMethod]
+ public void TestMoveRadioTelescopeToCoordinate_TriesMoveRadioTelescopeToCoordinateWithAnotherCommandRunning_AlreadyMoving()
+ {
+ MovementResult result0 = MovementResult.None;
+ MovementResult result1 = MovementResult.None;
+ MovementPriority priority = MovementPriority.Manual;
+
+ Coordinate c = new Coordinate();
+
+ // This is running two commands at the same time. One of them should succeed, while
+ // the other is rejected
+
+ Thread t0 = new Thread(() =>
+ {
+ result0 = TestRadioTelescopeController.MoveRadioTelescopeToCoordinate(c, priority);
+ });
+
+ Thread t1 = new Thread(() =>
+ {
+ result1 = TestRadioTelescopeController.MoveRadioTelescopeToCoordinate(c, priority);
+ });
+
+ t0.Start();
+ t1.Start();
+
+ t0.Join();
+ t1.Join();
+
+ Assert.IsTrue(result0 == MovementResult.Success || result1 == MovementResult.Success);
+ Assert.IsTrue(result0 == MovementResult.AlreadyMoving || result1 == MovementResult.AlreadyMoving);
+ }
+
+ [TestMethod]
+ public void TestMoveRadioTelescopeToOrientation_AllStatusesOK_Success()
+ {
+ Orientation o = new Orientation();
+
+ MovementResult result = TestRadioTelescopeController.MoveRadioTelescopeToOrientation(o, MovementPriority.Manual);
+
+ Assert.AreEqual(MovementResult.Success, result);
+ }
+
+ [TestMethod]
+ public void TestMoveRadioTelescopeToOrientation_SensorDataUnsafe_SensorsNotSafe()
+ {
+ TestRadioTelescopeController.overrides.setElevationMotTemp(false);
+ SensorNetworkServer.CurrentElevationMotorTemp[0].temp = 3000;
+ SensorNetworkServer.CurrentElevationMotorTemp[0].location_ID = (int)SensorLocationEnum.EL_MOTOR;
+
+ Orientation o = new Orientation();
+
+ Thread.Sleep(2000);
+
+ MovementResult result = TestRadioTelescopeController.MoveRadioTelescopeToOrientation(o, MovementPriority.Manual);
+
+ Assert.AreEqual(MovementResult.SensorsNotSafe, result);
+ }
+
+ [TestMethod]
+ public void TestMoveRadioTelescopeToOrientation_TriesMoveRadioTelescopeToOrientationWithAnotherCommandRunning_AlreadyMoving()
+ {
+ MovementResult result0 = MovementResult.None;
+ MovementResult result1 = MovementResult.None;
+ MovementPriority priority = MovementPriority.Manual;
+
+ // This is running two commands at the same time. One of them should succeed, while
+ // the other is rejected
+
+ Orientation o = new Orientation();
+
+ Thread t0 = new Thread(() =>
+ {
+ result0 = TestRadioTelescopeController.MoveRadioTelescopeToOrientation(o, priority);
+ });
+
+ Thread t1 = new Thread(() =>
+ {
+ result1 = TestRadioTelescopeController.MoveRadioTelescopeToOrientation(o, priority);
+ });
+
+ t0.Start();
+ t1.Start();
+
+ t0.Join();
+ t1.Join();
+
+ Assert.IsTrue(result0 == MovementResult.Success || result1 == MovementResult.Success);
+ Assert.IsTrue(result0 == MovementResult.AlreadyMoving || result1 == MovementResult.AlreadyMoving);
}
+ [TestMethod]
+ public void TestMoveRadioByxDegreesAllStatusesOK_Success()
+ {
+ Orientation o = new Orientation(-20,70);
+
+ MovementResult result = TestRadioTelescopeController.MoveRadioTelescopeByXDegrees(o, MovementPriority.Manual);
+
+ Assert.AreEqual(MovementResult.Success, result);
+ //verify move within 1/10th of a degree
+ Assert.AreEqual(TestRadioTelescopeController.GetCurrentOrientation().Azimuth,340, 0.1);
+ Assert.AreEqual(TestRadioTelescopeController.GetCurrentOrientation().Elevation, 70,0.1);
+
+ }
- [ClassCleanup]
- public static void BringDown()
+ [TestMethod]
+ public void TestMoveRadioTelescopeByxDegrees_SensorDataUnsafe_SensorsNotSafe()
{
- //TestRadioTelescopeController.RadioTelescope.PLCClient.TerminateTCPServerConnection();
- //TestRTPLC.RequestStopAsyncAcceptingClientsAndJoin();
- TestRadioTelescopeController.RadioTelescope.PLCDriver.Bring_down();
+ TestRadioTelescopeController.overrides.setElevationMotTemp(false);
+ SensorNetworkServer.CurrentElevationMotorTemp[0].temp = 3000;
+ SensorNetworkServer.CurrentElevationMotorTemp[0].location_ID = (int)SensorLocationEnum.EL_MOTOR;
+
+ Orientation o = new Orientation();
+
+ Thread.Sleep(2000);
+
+ MovementResult result = TestRadioTelescopeController.MoveRadioTelescopeByXDegrees(o, MovementPriority.Manual);
+
+ Assert.AreEqual(MovementResult.SensorsNotSafe, result);
+ }
+
+ [TestMethod]
+ public void TestMoveRadioTelescopeToByxDegrees_TriesMoveRadioTelescopeToOrientationWithAnotherCommandRunning_AlreadyMoving()
+ {
+ MovementResult result0 = MovementResult.None;
+ MovementResult result1 = MovementResult.None;
+ MovementPriority priority = MovementPriority.Manual;
+
+ // This is running two commands at the same time. One of them should succeed, while
+ // the other is rejected
+
+ Orientation o = new Orientation();
+
+ Thread t0 = new Thread(() =>
+ {
+ result0 = TestRadioTelescopeController.MoveRadioTelescopeByXDegrees(o, priority);
+ });
+
+ Thread t1 = new Thread(() =>
+ {
+ result1 = TestRadioTelescopeController.MoveRadioTelescopeByXDegrees(o, priority);
+ });
+
+ t0.Start();
+ t1.Start();
+
+ t0.Join();
+ t1.Join();
+
+ Assert.IsTrue(result0 == MovementResult.Success || result1 == MovementResult.Success);
+ Assert.IsTrue(result0 == MovementResult.AlreadyMoving || result1 == MovementResult.AlreadyMoving);
+ }
+
+ [TestMethod]
+ public void TestMoveRadioByxDegreesAzAboveThreshold()
+ {
+ Orientation o = new Orientation(1024, 20);
+
+ MovementResult result = TestRadioTelescopeController.MoveRadioTelescopeByXDegrees(o, MovementPriority.Manual);
+
+ Assert.AreEqual(MovementResult.RequestedAzimuthMoveTooLarge, result);
+
+ //ensure that the telescope did not move in either dimension
+ Assert.AreEqual(TestRadioTelescopeController.GetCurrentOrientation().Azimuth,0, 0.1);
+ Assert.AreEqual(TestRadioTelescopeController.GetCurrentOrientation().Elevation, 0,0.1);
+ }
+
+ [TestMethod]
+ public void TestMoveRadioByxDegreesInvalidReuqestedPosition()
+ {
+ Orientation o = new Orientation(0, -300);
+
+ MovementResult result = TestRadioTelescopeController.MoveRadioTelescopeByXDegrees(o, MovementPriority.Manual);
+
+ Assert.AreEqual(MovementResult.InvalidRequestedPostion, result);
+
+ //ensure that the telescope did not move in either dimension
+ Assert.AreEqual(TestRadioTelescopeController.GetCurrentOrientation().Azimuth, 0);
+ Assert.AreEqual(TestRadioTelescopeController.GetCurrentOrientation().Elevation, 0);
+ }
+
+ [TestMethod]
+ public void TestThermalCalibrateRadioTelescope_AllStatusesOK_Success()
+ {
+ MovementResult result = TestRadioTelescopeController.ThermalCalibrateRadioTelescope(MovementPriority.Manual);
+
+ Assert.AreEqual(MovementResult.Success, result);
+ }
+
+ [TestMethod]
+ public void TestThermalCalibrateRadioTelescope_SensorDataUnsafe_SensorsNotSafe()
+ {
+ TestRadioTelescopeController.overrides.setElevationMotTemp(false);
+ SensorNetworkServer.CurrentElevationMotorTemp[0].temp = 3000;
+ SensorNetworkServer.CurrentElevationMotorTemp[0].location_ID = (int)SensorLocationEnum.EL_MOTOR;
+
+ Thread.Sleep(2000);
+
+ MovementResult result = TestRadioTelescopeController.ThermalCalibrateRadioTelescope(MovementPriority.Manual);
+
+ Assert.AreEqual(MovementResult.SensorsNotSafe, result);
+ }
+
+ [TestMethod]
+ public void TestThermalCalibrateRadioTelescope_TriesThermalCalibrateRadioTelescopeWithAnotherCommandRunning_AlreadyMoving()
+ {
+ MovementResult result0 = MovementResult.None;
+ MovementResult result1 = MovementResult.None;
+ MovementPriority priority = MovementPriority.Manual;
+
+ // This is running two commands at the same time. One of them should succeed, while
+ // the other is rejected
+
+ Thread t0 = new Thread(() =>
+ {
+ result0 = TestRadioTelescopeController.ThermalCalibrateRadioTelescope(priority);
+ });
+
+ Thread t1 = new Thread(() =>
+ {
+ result1 = TestRadioTelescopeController.ThermalCalibrateRadioTelescope(priority);
+ });
+
+ t0.Start();
+ t1.Start();
+
+ t0.Join();
+ t1.Join();
+
+ Assert.IsTrue(result0 == MovementResult.Success || result1 == MovementResult.Success);
+ Assert.IsTrue(result0 == MovementResult.AlreadyMoving || result1 == MovementResult.AlreadyMoving);
+ }
+
+ [TestMethod]
+ public void TestHomeTelescope_TriesHomeTelescopeWithAnotherCommandRunning_AlreadyMoving()
+ {
+ MovementResult result0 = MovementResult.None;
+ MovementResult result1 = MovementResult.None;
+ MovementPriority priority = MovementPriority.Manual;
+
+ // This is running two commands at the same time. One of them should succeed, while
+ // the other is rejected
+
+ Thread t0 = new Thread(() =>
+ {
+ result0 = TestRadioTelescopeController.HomeTelescope(priority);
+ });
+
+ Thread t1 = new Thread(() =>
+ {
+ result1 = TestRadioTelescopeController.HomeTelescope(priority);
+ });
+
+ t0.Start();
+ t1.Start();
+
+ t0.Join();
+ t1.Join();
+
+ Assert.IsTrue(result0 == MovementResult.Success || result1 == MovementResult.Success);
+ Assert.IsTrue(result0 == MovementResult.AlreadyMoving || result1 == MovementResult.AlreadyMoving);
+ }
+
+ ///
+ /// This is a heavy stress test to verify that our movements are thread safe. Meaning, if one current thread is
+ /// executing a movement, it is impossible for another thread to begin one (unless safely interrupted).
+ ///
+ /// This test is specifically testing that if threadCount number of movements are run at the same time, only one
+ /// succeeds, and the rest will return back an error code.
+ ///
+ /// This should never happen in production, but the premise still exists that we want movements to be thread safe,
+ /// stable and reliable.
+ ///
+ [TestMethod]
+ public void TestAllTelescopeMovements_RunABunchOfCommandsAtTheSameTime_OnlyOneCommandSucceedsWhileTheRestAreAlreadyMoving()
+ {
+ int threadCount = 8;
+
+ MovementPriority priority = MovementPriority.Manual;
+ Coordinate c = new Coordinate(0, 0);
+ Orientation o = new Orientation(0, 0);
+
+ // movement result array
+ MovementResult[] results = new MovementResult[threadCount];
+ for (int i = 0; i < threadCount; i++)
+ results[i] = MovementResult.None;
+
+ Thread[] threads = new Thread[threadCount];
+
+ threads[0] = new Thread(() =>
+ {
+ results[0] = TestRadioTelescopeController.HomeTelescope(priority);
+ });
+ threads[1] = new Thread(() =>
+ {
+ results[1] = TestRadioTelescopeController.SnowDump(priority);
+ });
+ threads[2] = new Thread(() =>
+ {
+ results[2] = TestRadioTelescopeController.MoveRadioTelescopeToCoordinate(c, priority);
+ });
+ threads[3] = new Thread(() =>
+ {
+ results[3] = TestRadioTelescopeController.MoveRadioTelescopeToOrientation(o, priority);
+ });
+ threads[4] = new Thread(() =>
+ {
+ results[4] = TestRadioTelescopeController.ThermalCalibrateRadioTelescope(priority);
+ });
+ threads[5] = new Thread(() =>
+ {
+ results[5] = TestRadioTelescopeController.StartRadioTelescopeJog(5, RadioTelescopeDirectionEnum.ClockwiseOrNegative, RadioTelescopeAxisEnum.AZIMUTH);
+ });
+ threads[6] = new Thread(() =>
+ {
+ results[6] = TestRadioTelescopeController.FullElevationMove(priority);
+ });
+ threads[7] = new Thread(() =>
+ {
+ results[7] = TestRadioTelescopeController.MoveRadioTelescopeByXDegrees(o, priority);
+ });
+
+ // Run all threads concurrently
+ // These cannot be looped through because a loop adds enough delay to throw off concurrency
+ threads[0].Start();
+ threads[1].Start();
+ threads[2].Start();
+ threads[3].Start();
+ threads[4].Start();
+ threads[5].Start();
+ threads[6].Start();
+ threads[7].Start();
+
+ // Wait for all threads to complete
+ foreach (Thread thread in threads)
+ {
+ thread.Join();
+ }
+
+ int successes = 0;
+ int alreadyMovings = 0;
+
+ for (int i = 0; i < threadCount; i++)
+ {
+ if (results[i] == MovementResult.Success) successes++;
+ else if (results[i] == MovementResult.AlreadyMoving) alreadyMovings++;
+ }
+
+ Assert.AreEqual(1, successes);
+ Assert.AreEqual(threadCount - 1, alreadyMovings);
}
}
}
+
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/PacketDecodingToolsTest.cs b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/PacketDecodingToolsTest.cs
new file mode 100644
index 00000000..f7379252
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/PacketDecodingToolsTest.cs
@@ -0,0 +1,290 @@
+using ControlRoomApplication.Controllers.SensorNetwork;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using ControlRoomApplication.Entities;
+using EmbeddedSystemsTest.SensorNetworkSimulation;
+
+namespace ControlRoomApplicationTest.EntityControllersTests.SensorNetworkTests
+{
+ [TestClass]
+ public class PacketDecodingToolsTest
+ {
+ [TestMethod]
+ public void TestGetAccelerationFromBytes_BytesToAcceleration_ReturnsAcceleration()
+ {
+ // The byte size for one acceleration is 6 bytes, because each axis takes up 2 bytes,
+ // and there are 3 axes.
+ byte[] oneAcceleration = new byte[16];
+
+ // Create acceleration with timestamp of UTC 1
+ oneAcceleration[0] = 0;
+ oneAcceleration[1] = 0;
+ oneAcceleration[2] = 0;
+ oneAcceleration[3] = 0;
+ oneAcceleration[4] = 0;
+ oneAcceleration[5] = 0;
+ oneAcceleration[6] = 0;
+ oneAcceleration[7] = 1;
+
+ // Create acceleration with a size 1 FIFO dump
+ oneAcceleration[8] = 0;
+ oneAcceleration[9] = 1;
+
+ // This will create an acceleration with x, y and z axes as 1, 2 and 3 respectively
+ oneAcceleration[10] = 0;
+ oneAcceleration[11] = 1;
+ oneAcceleration[12] = 0;
+ oneAcceleration[13] = 2;
+ oneAcceleration[14] = 0;
+ oneAcceleration[15] = 3;
+
+ Acceleration[] expected = new Acceleration[1];
+ expected[0] = Acceleration.Generate(1, 1, 2, 3, SensorLocationEnum.COUNTERBALANCE);
+
+ // This is only used for the counter, becuase it needs a variable to be passed by reference
+ int i = 0;
+
+ var result = PacketDecodingTools.GetAccelerationFromBytes(ref i, oneAcceleration, 1, SensorLocationEnum.COUNTERBALANCE);
+
+ Assert.AreEqual(1, result.Length); // Only expecting one result
+ Assert.AreEqual(expected[0].TimeCaptured, result[0].TimeCaptured);
+ Assert.AreEqual(expected[0].x, result[0].x);
+ Assert.AreEqual(expected[0].y, result[0].y);
+ Assert.AreEqual(expected[0].z, result[0].z);
+ Assert.AreEqual(expected[0].location_ID, result[0].location_ID);
+ }
+
+ [TestMethod]
+ public void TestGetAccelerationFromBytes_BytesToMultipleAcceleration_ReturnsMultipleAcceleration()
+ {
+ // The byte size for one acceleration is 6 bytes, because each axis takes up 2 bytes,
+ // and there are 3 axes.
+ byte[] twoAcceleration = new byte[22];
+
+ // Create acceleration with timestamp of UTC 1
+ twoAcceleration[0] = 0;
+ twoAcceleration[1] = 0;
+ twoAcceleration[2] = 0;
+ twoAcceleration[3] = 0;
+ twoAcceleration[4] = 0;
+ twoAcceleration[5] = 0;
+ twoAcceleration[6] = 0;
+ twoAcceleration[7] = 1;
+
+ // Create acceleration with a size 2 FIFO dump
+ twoAcceleration[8] = 0;
+ twoAcceleration[9] = 2;
+
+ // This will create two acceleration results with x, y and z axes as 1, 2 and 3 respectively
+ twoAcceleration[10] = 0;
+ twoAcceleration[11] = 1;
+ twoAcceleration[12] = 0;
+ twoAcceleration[13] = 2;
+ twoAcceleration[14] = 0;
+ twoAcceleration[15] = 3;
+ twoAcceleration[16] = 0;
+ twoAcceleration[17] = 1;
+ twoAcceleration[18] = 0;
+ twoAcceleration[19] = 2;
+ twoAcceleration[20] = 0;
+ twoAcceleration[21] = 3;
+
+ Acceleration[] expected = new Acceleration[2];
+ expected[0] = Acceleration.Generate(1 - (long)(1 / SensorNetworkConstants.CbAccelSamplingFrequency * 1000), 1, 2, 3, SensorLocationEnum.COUNTERBALANCE);
+ expected[1] = Acceleration.Generate(1, 1, 2, 3, SensorLocationEnum.COUNTERBALANCE); // Temporary, will change when the Control Room can configure accelerometers
+
+ // This is only used for the counter, becuase it needs a variable to be passed by reference
+ int i = 0;
+
+ var result = PacketDecodingTools.GetAccelerationFromBytes(ref i, twoAcceleration, 1, SensorLocationEnum.COUNTERBALANCE);
+
+ Assert.AreEqual(2, result.Length); // Expecting two results
+
+ Assert.AreEqual(expected[0].TimeCaptured, result[0].TimeCaptured);
+
+ Assert.AreEqual(expected[0].x, result[0].x);
+ Assert.AreEqual(expected[0].y, result[0].y);
+ Assert.AreEqual(expected[0].z, result[0].z);
+ Assert.AreEqual(expected[0].location_ID, result[0].location_ID);
+
+ Assert.AreEqual(expected[1].TimeCaptured, result[1].TimeCaptured);
+
+ Assert.AreEqual(expected[1].x, result[1].x);
+ Assert.AreEqual(expected[1].y, result[1].y);
+ Assert.AreEqual(expected[1].z, result[1].z);
+ Assert.AreEqual(expected[1].location_ID, result[1].location_ID);
+ }
+
+ [TestMethod]
+ public void TestGetTemperatureFromBytes_BytesToTemperature_ReturnsTemperature()
+ {
+ // The byte size for one temperature is 2 bytes
+ byte[] oneTemperature = new byte[2];
+
+ // This will create temperature value of 1, because the temperature is divided by 16
+ oneTemperature[0] = 0;
+ oneTemperature[1] = 16;
+
+ // Skipping the timestamp because we aren't concerned with that in this test
+ Temperature[] expected = new Temperature[1];
+ expected[0] = Temperature.Generate(0, 1, SensorLocationEnum.COUNTERBALANCE);
+
+ // This is only used for the counter, becuase it needs a variable to be passed by reference
+ int i = 0;
+
+ var result = PacketDecodingTools.GetTemperatureFromBytes(ref i, oneTemperature, 1, SensorLocationEnum.COUNTERBALANCE);
+
+ Assert.AreEqual(1, result.Length); // Only expecting one result
+
+ Assert.AreEqual(expected[0].temp, result[0].temp);
+ Assert.AreEqual(expected[0].location_ID, result[0].location_ID);
+ }
+
+ [TestMethod]
+ public void TestGetTemperatureFromBytes_BytesToMultipleTemperatures_ReturnsMultipleTemperatures()
+ {
+ // The byte size for one temperature is 2 bytes
+ byte[] twoTemperature = new byte[4];
+
+ // This will create temperature value of 1, because the temperature is divided by 16
+ twoTemperature[0] = 0;
+ twoTemperature[1] = 16;
+ twoTemperature[2] = 0;
+ twoTemperature[3] = 16;
+
+ // Skipping the timestamp because we aren't concerned with that in this test
+ Temperature[] expected = new Temperature[2];
+ expected[0] = Temperature.Generate(0, 1, SensorLocationEnum.COUNTERBALANCE);
+ expected[1] = Temperature.Generate(0, 1, SensorLocationEnum.COUNTERBALANCE);
+
+ // This is only used for the counter, becuase it needs a variable to be passed by reference
+ int i = 0;
+
+ var result = PacketDecodingTools.GetTemperatureFromBytes(ref i, twoTemperature, 2, SensorLocationEnum.COUNTERBALANCE);
+
+ Assert.AreEqual(2, result.Length); // Expecting two results
+
+ Assert.AreEqual(expected[0].temp, result[0].temp);
+ Assert.AreEqual(expected[0].location_ID, result[0].location_ID);
+
+ Assert.AreEqual(expected[1].temp, result[1].temp);
+ Assert.AreEqual(expected[1].location_ID, result[1].location_ID);
+ }
+
+ [TestMethod]
+ public void TestGetAzimuthAxisPositionFromBytes_BytesToPosition_ReturnsPosition()
+ {
+ // byte size for an axis position is 2 bytes
+ byte[] pos = new byte[2];
+
+ // Encode
+ int i = 0;
+
+ // 310 is 50 degrees away from 0, on the opposite end of 50
+ double expected = 50;
+ short encoded = PacketEncodingTools.ConvertDegreesToRawAzData(expected);
+ PacketEncodingTools.Add16BitValueToByteArray(ref pos, ref i, encoded);
+
+ // Decode
+ i = 0;
+ int offset = 0;
+
+ double result = PacketDecodingTools.GetAzimuthAxisPositionFromBytes(ref i, pos, offset, 0);
+
+ Assert.AreEqual(expected, result, 0.16);
+ }
+
+ [TestMethod]
+ public void TestGetAzimuthAxisPositionFromBytes_BytesToPositionWithOffset_ReturnsNormalizedPosition()
+ {
+ // byte size for an axis position is 2 bytes
+ byte[] pos = new byte[2];
+
+ // Encode
+ int i = 0;
+ double initialValue = 50;
+ short encoded = PacketEncodingTools.ConvertDegreesToRawAzData(initialValue);
+ PacketEncodingTools.Add16BitValueToByteArray(ref pos, ref i, encoded);
+
+ // Decode
+ i = 0;
+ // With an offset of 60, that would make the origination originally -10, but with normalization, it should be 350
+ int offset = 60;
+
+ double expected = 350;
+
+ double result = PacketDecodingTools.GetAzimuthAxisPositionFromBytes(ref i, pos, offset, 0);
+
+ Assert.AreEqual(expected, result, 0.16);
+ }
+
+ [TestMethod]
+ public void TestGetAzimuthAxisPositionFromBytes_CalculatedGreaterThan360_ReturnsOriginalValue()
+ {
+ // byte size for an axis position is 2 bytes
+ byte[] pos = new byte[2];
+
+ // Encode
+ int i = 0;
+ double initialValue = 361;
+ short encoded = PacketEncodingTools.ConvertDegreesToRawAzData(initialValue);
+ PacketEncodingTools.Add16BitValueToByteArray(ref pos, ref i, encoded);
+
+ // Decode
+ i = 0;
+ int offset = 0;
+
+ int expected = 10;
+
+ double result = PacketDecodingTools.GetAzimuthAxisPositionFromBytes(ref i, pos, offset, 10);
+
+ Assert.AreEqual(expected, result, 0.16);
+ }
+
+ [TestMethod]
+ public void TestGetElevationAxisPositionFromBytes_BytesToPosition_ReturnsPosition()
+ {
+ // byte size for an axis position is 2 bytes
+ byte[] pos = new byte[2];
+
+ // Encode
+ int i = 0;
+ double expected = 50;
+ short encoded = PacketEncodingTools.ConvertDegreesToRawElData(expected);
+ PacketEncodingTools.Add16BitValueToByteArray(ref pos, ref i, encoded);
+
+ // Decode
+ i = 0;
+ int offset = 0;
+
+ double result = PacketDecodingTools.GetElevationAxisPositionFromBytes(ref i, pos, offset, 0);
+
+ Assert.AreEqual(expected, result, 0.16);
+ }
+
+ [TestMethod]
+ public void TestGetElevationAxisPositionFromBytes_BytesToPositionWithOffset_ReturnsPosition()
+ {
+ // byte size for an axis position is 2 bytes
+ byte[] pos = new byte[2];
+
+ // Encode
+ int i = 0;
+ double expected = 50;
+ short encoded = PacketEncodingTools.ConvertDegreesToRawElData(expected);
+ PacketEncodingTools.Add16BitValueToByteArray(ref pos, ref i, encoded);
+
+ // Decode
+ i = 0;
+ int offset = 10;
+
+ double result = PacketDecodingTools.GetElevationAxisPositionFromBytes(ref i, pos, offset, 0);
+
+ Assert.AreEqual(expected - offset, result, 0.16);
+ }
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/SensorNetworkClientTest.cs b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/SensorNetworkClientTest.cs
new file mode 100644
index 00000000..c1617a09
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/SensorNetworkClientTest.cs
@@ -0,0 +1,194 @@
+using ControlRoomApplication.Controllers.SensorNetwork;
+using ControlRoomApplication.Database;
+using ControlRoomApplication.Entities;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Net.Sockets;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace ControlRoomApplicationTest.EntityControllersTests
+{
+ [TestClass]
+ public class SensorNetworkClientTest
+ {
+
+ // These are fields that will remain the same for all tests
+ string IpAddress = "127.0.0.1";
+ int TelescopeId = 5;
+ int Port = 3000;
+ SensorNetworkClient client;
+
+ [TestInitialize]
+ public void Initialize()
+ {
+ client = new SensorNetworkClient(IpAddress, Port, TelescopeId);
+ }
+
+ [TestCleanup]
+ public void Cleanup()
+ {
+ DatabaseOperations.DeleteSensorNetworkConfig(client.SensorNetworkConfig);
+ }
+
+ [TestMethod]
+ public void TestSensorNetworkClient_Initialization_PopulatesFields()
+ {
+ // Used to access private fields of a class for testing
+ PrivateObject privClient = new PrivateObject(client);
+
+ Assert.IsTrue(((string)privClient.GetFieldOrProperty("IPAddress")).Equals(IpAddress));
+ Assert.IsTrue((int)privClient.GetFieldOrProperty("Port") == Port);
+ Assert.IsTrue(client.SensorNetworkConfig.TelescopeId == TelescopeId);
+ }
+
+ [TestMethod]
+ public void TestSensorNetworkClient_InitializationNewTelescope_CreatesNewConfig()
+ {
+ int newTelescopeId = 10;
+
+ // Config should not exist
+ var retrievedConfig = DatabaseOperations.RetrieveSensorNetworkConfigByTelescopeId(newTelescopeId);
+ Assert.IsNull(retrievedConfig);
+
+ // Create new client, which will create a new config for the telescope ID if it doesn't exist
+ SensorNetworkClient newClient = new SensorNetworkClient(IpAddress, Port, newTelescopeId);
+
+ // Config should now exist and be equal to the one in the client
+ retrievedConfig = DatabaseOperations.RetrieveSensorNetworkConfigByTelescopeId(newTelescopeId);
+ Assert.IsTrue(retrievedConfig.Equals(newClient.SensorNetworkConfig));
+
+ // Delete config after use
+ DatabaseOperations.DeleteSensorNetworkConfig(retrievedConfig);
+ }
+
+ [TestMethod]
+ public void TestSensorNetworkClient_InitializationExistingTelescope_LoadsExistingConfig()
+ {
+ // Config should exist
+ var retrievedConfig = DatabaseOperations.RetrieveSensorNetworkConfigByTelescopeId(TelescopeId);
+
+ // Create new client which will pull an existing config
+ SensorNetworkClient existingClient = new SensorNetworkClient(IpAddress, Port, TelescopeId);
+
+ // Config should exist and be equal to the one in the client
+ Assert.IsTrue(retrievedConfig.Equals(existingClient.SensorNetworkConfig));
+ }
+
+ [TestMethod]
+ public void TestSensorNetworkClient_SendSensorInitializationAllBytes1_CorrectDataReceived()
+ {
+ byte[] result = new byte[0];
+
+ // We must create a separate thread for the simulated server to run on
+ Thread snServer = new Thread(() => {
+
+ // Start server
+ TcpListener listener = new TcpListener(IPAddress.Parse(IpAddress), Port);
+ listener.Start();
+
+ // Create local client/stream to receive data
+ TcpClient localClient = listener.AcceptTcpClient();
+ NetworkStream stream = localClient.GetStream();
+
+ // This will hold our sensor initialization
+ byte[] bytes = new byte[SensorNetworkConstants.SensorNetworkSensorCount];
+
+ // Wait for initialization
+ stream.Read(bytes, 0, bytes.Length);
+
+ // If we reach here, we've received data
+ result = bytes;
+
+ localClient.Close();
+ localClient.Dispose();
+ stream.Close();
+ stream.Dispose();
+ listener.Stop();
+ });
+
+ // Start server, which will begin waiting for the init byte array
+ snServer.Start();
+
+ // Send the init byte array
+ bool succeeded = client.SendSensorInitialization();
+
+ snServer.Join();
+
+ // This is what we expect to see on the other end
+ var expected = client.SensorNetworkConfig.GetSensorInitAsBytes();
+
+ Assert.IsTrue(succeeded);
+ Assert.IsTrue(expected.SequenceEqual(result));
+ }
+
+ [TestMethod]
+ public void TestSensorNetworkClient_SendSensorInitializationAllBytes0_CorrectDataReceived()
+ {
+ byte[] result = new byte[0];
+
+ // We must create a separate thread for the simulated server to run on
+ Thread snServer = new Thread(() => {
+
+ // Start server
+ TcpListener listener = new TcpListener(IPAddress.Parse(IpAddress), Port);
+ listener.Start();
+
+ // Create local client/stream to receive data
+ TcpClient localClient = listener.AcceptTcpClient();
+ NetworkStream stream = localClient.GetStream();
+
+ // This will hold our sensor initialization
+ byte[] bytes = new byte[SensorNetworkConstants.SensorNetworkSensorCount];
+
+ // Wait for initialization
+ stream.Read(bytes, 0, bytes.Length);
+
+ // If we reach here, we've received data
+ result = bytes;
+
+ localClient.Close();
+ localClient.Dispose();
+ stream.Close();
+ stream.Dispose();
+ listener.Stop();
+ });
+
+ // Start server, which will begin waiting for the init byte array
+ snServer.Start();
+
+ // Flip sensor initialization bytes to 0
+ client.SensorNetworkConfig.ElevationTemp1Init = false;
+ client.SensorNetworkConfig.AzimuthTemp1Init = false;
+ client.SensorNetworkConfig.AzimuthAccelerometerInit = false;
+ client.SensorNetworkConfig.ElevationAccelerometerInit = false;
+ client.SensorNetworkConfig.CounterbalanceAccelerometerInit = false;
+ client.SensorNetworkConfig.ElevationEncoderInit = false;
+ client.SensorNetworkConfig.AzimuthEncoderInit = false;
+
+ // Send the init byte array
+ bool succeeded = client.SendSensorInitialization();
+
+ snServer.Join();
+
+ // This is what we expect to see on the other end
+ var expected = client.SensorNetworkConfig.GetSensorInitAsBytes();
+
+ Assert.IsTrue(succeeded);
+ Assert.IsTrue(expected.SequenceEqual(result));
+ }
+
+ [TestMethod]
+ public void TestSensorNetworkClient_NoServerToConnectTo_Fail()
+ {
+ // This will fail because there is no server to connect to
+ bool succeeded = client.SendSensorInitialization();
+
+ Assert.IsFalse(succeeded);
+ }
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/SensorNetworkServerTest.cs b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/SensorNetworkServerTest.cs
new file mode 100644
index 00000000..faf1491a
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/SensorNetworkServerTest.cs
@@ -0,0 +1,886 @@
+using ControlRoomApplication.Controllers.SensorNetwork;
+using ControlRoomApplication.Database;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Net.Sockets;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Timers;
+
+namespace ControlRoomApplicationTest.EntityControllersTests
+{
+ [TestClass]
+ public class SensorNetworkServerTest
+ {
+
+ // These are fields that will remain the same for all tests
+ IPAddress ServerIpAddress = IPAddress.Parse("127.0.0.1");
+ string ClientIpAddress = "127.0.0.2";
+ int ClientPort = 3000;
+ int ServerPort = 3001;
+ int TelescopeId = 5;
+ bool IsSimulation = false;
+ SensorNetworkServer Server;
+ string TestPacketDirectory = "../../EntityControllersTests/SensorNetworkTests/SensorNetworkTestPackets/";
+
+
+ [TestInitialize]
+ public void Initialize()
+ {
+ Server = new SensorNetworkServer(ServerIpAddress, ServerPort, ClientIpAddress, ClientPort, TelescopeId, IsSimulation);
+ }
+
+ [TestCleanup]
+ public void Cleanup()
+ {
+ DatabaseOperations.DeleteSensorNetworkConfig(Server.InitializationClient.SensorNetworkConfig);
+ }
+
+ [TestMethod]
+ public void TestSensorNetworkServer_Initialization_Success()
+ {
+ PrivateObject privServer = new PrivateObject(Server);
+ PrivateObject privClient = new PrivateObject(Server.InitializationClient);
+
+ // Arrange/Act
+ TcpListener resultListener = (TcpListener)privServer.GetFieldOrProperty("Server");
+ Thread resultMonitorThread = (Thread)privServer.GetFieldOrProperty("SensorMonitoringThread");
+ System.Timers.Timer resultTimer = (System.Timers.Timer)privServer.GetFieldOrProperty("Timeout");
+
+ // Verify SensorNetworkServer is correct
+ Assert.IsNotNull(resultListener);
+ Assert.AreEqual(((IPEndPoint)resultListener.LocalEndpoint).Address, ServerIpAddress);
+ Assert.AreEqual(((IPEndPoint)resultListener.LocalEndpoint).Port, ServerPort);
+
+ // Verify SensorNetworkClient is correct
+ Assert.IsNotNull(Server.InitializationClient);
+ Assert.AreEqual((string)privClient.GetFieldOrProperty("IPAddress"), ClientIpAddress);
+ Assert.AreEqual((int)privClient.GetFieldOrProperty("Port"), ClientPort);
+ Assert.AreEqual(Server.InitializationClient.SensorNetworkConfig.TelescopeId, TelescopeId);
+
+ // Verify temperatures are correct
+ Assert.IsNotNull(Server.CurrentElevationMotorTemp);
+ Assert.IsNotNull(Server.CurrentAzimuthMotorTemp);
+
+ // Verify orientation is correct
+ Assert.IsNotNull(Server.CurrentAbsoluteOrientation);
+
+ // Verify acceleration is correct
+ Assert.IsNotNull(Server.CurrentAzimuthMotorAccl);
+ Assert.IsNotNull(Server.CurrentElevationMotorAccl);
+ Assert.IsNotNull(Server.CurrentCounterbalanceAccl);
+
+ // Verify thread is correct
+ Assert.IsNotNull(resultMonitorThread);
+ Assert.AreEqual(resultMonitorThread.Name, "SensorMonitorThread");
+
+ // Verify timer is correct
+ Assert.IsNotNull(resultTimer);
+ Assert.IsFalse(resultTimer.AutoReset);
+ }
+
+ [TestMethod]
+ public void TestInterpretData_AllSensorsInitialized_InterpretsData()
+ {
+ // This is a test packet where all sensors are initialized, and
+ // all of their values are set to 50
+ byte[] AllData50 = File.ReadAllBytes($"{TestPacketDirectory}AllData50.snp");
+
+ PrivateObject privServer = new PrivateObject(Server);
+
+ int expectedValue = 50;
+
+ // Call the function, which decodes the data
+ bool success = (bool)privServer.Invoke("InterpretData", AllData50, AllData50.Length);
+
+ Assert.IsTrue(success);
+
+ // Verify all of the values are as expected; converted values have a small margin of error
+ Assert.AreEqual(Server.CurrentElevationMotorTemp[0].temp, expectedValue, 0.1);
+ Assert.AreEqual(Server.CurrentAzimuthMotorTemp[0].temp, expectedValue, 0.1);
+
+ Assert.AreEqual(Server.CurrentElevationMotorAccl[0].x, expectedValue);
+ Assert.AreEqual(Server.CurrentElevationMotorAccl[0].y, expectedValue);
+ Assert.AreEqual(Server.CurrentElevationMotorAccl[0].z, expectedValue);
+
+ Assert.AreEqual(Server.CurrentAzimuthMotorAccl[0].x, expectedValue);
+ Assert.AreEqual(Server.CurrentAzimuthMotorAccl[0].y, expectedValue);
+ Assert.AreEqual(Server.CurrentAzimuthMotorAccl[0].z, expectedValue);
+
+ Assert.AreEqual(Server.CurrentCounterbalanceAccl[0].x, expectedValue);
+ Assert.AreEqual(Server.CurrentCounterbalanceAccl[0].y, expectedValue);
+ Assert.AreEqual(Server.CurrentCounterbalanceAccl[0].z, expectedValue);
+
+ // 0.1 is the approximate margin of error with the conversions
+ Assert.AreEqual(Server.CurrentAbsoluteOrientation.Elevation, expectedValue, 0.16);
+ Assert.AreEqual(Server.CurrentAbsoluteOrientation.Azimuth, expectedValue, 0.16);
+ }
+
+ [TestMethod]
+ public void TestInterpretData_OnlyElTemp_InterpretsOnlyElTemp()
+ {
+ // Only the elevation temperature is initialized and should decode to the temp in Celsius
+ byte[] OnlyElTemp50C = File.ReadAllBytes($"{TestPacketDirectory}OnlyElTemp50C.snp");
+
+ PrivateObject privServer = new PrivateObject(Server);
+
+ int expectedValue = 50;
+
+ // Call the function, which decodes the data
+ bool success = (bool)privServer.Invoke("InterpretData", OnlyElTemp50C, OnlyElTemp50C.Length);
+
+ Assert.IsTrue(success);
+
+ // Verify all of the values are as expected; converted values have a small margin of error
+ Assert.AreEqual(Server.CurrentElevationMotorTemp[0].temp, expectedValue, 0.1);
+
+ // The rest of the values should be EMPTY (aka 0)
+ Assert.AreEqual(Server.CurrentAzimuthMotorTemp[0].temp, 0);
+
+ Assert.AreEqual(Server.CurrentElevationMotorAccl[0].x, 0);
+ Assert.AreEqual(Server.CurrentElevationMotorAccl[0].y, 0);
+ Assert.AreEqual(Server.CurrentElevationMotorAccl[0].z, 0);
+
+ Assert.AreEqual(Server.CurrentAzimuthMotorAccl[0].x, 0);
+ Assert.AreEqual(Server.CurrentAzimuthMotorAccl[0].y, 0);
+ Assert.AreEqual(Server.CurrentAzimuthMotorAccl[0].z, 0);
+
+ Assert.AreEqual(Server.CurrentCounterbalanceAccl[0].x, 0);
+ Assert.AreEqual(Server.CurrentCounterbalanceAccl[0].y, 0);
+ Assert.AreEqual(Server.CurrentCounterbalanceAccl[0].z, 0);
+
+ Assert.AreEqual(Server.CurrentAbsoluteOrientation.Elevation, 0);
+ Assert.AreEqual(Server.CurrentAbsoluteOrientation.Azimuth, 0);
+ }
+
+ [TestMethod]
+ public void TestInterpretData_OnlyAzTemp_InterpretsOnlyAzTemp()
+ {
+ // Only the azimuth temperature is initialized and should decode to the temp in Celsius
+ byte[] OnlyAzTemp50C = File.ReadAllBytes($"{TestPacketDirectory}OnlyAzTemp50C.snp");
+
+ PrivateObject privServer = new PrivateObject(Server);
+
+ int expectedValue = 50;
+
+ // Call the function, which decodes the data
+ bool success = (bool)privServer.Invoke("InterpretData", OnlyAzTemp50C, OnlyAzTemp50C.Length);
+
+ Assert.IsTrue(success);
+
+ // Verify all of the values are as expected; converted values have a small margin of error
+ Assert.AreEqual(Server.CurrentElevationMotorTemp[0].temp, 0);
+ Assert.AreEqual(Server.CurrentAzimuthMotorTemp[0].temp, expectedValue, 0.1); // This should be the only populated value
+
+ Assert.AreEqual(Server.CurrentElevationMotorAccl[0].x, 0);
+ Assert.AreEqual(Server.CurrentElevationMotorAccl[0].y, 0);
+ Assert.AreEqual(Server.CurrentElevationMotorAccl[0].z, 0);
+
+ Assert.AreEqual(Server.CurrentAzimuthMotorAccl[0].x, 0);
+ Assert.AreEqual(Server.CurrentAzimuthMotorAccl[0].y, 0);
+ Assert.AreEqual(Server.CurrentAzimuthMotorAccl[0].z, 0);
+
+ Assert.AreEqual(Server.CurrentCounterbalanceAccl[0].x, 0);
+ Assert.AreEqual(Server.CurrentCounterbalanceAccl[0].y, 0);
+ Assert.AreEqual(Server.CurrentCounterbalanceAccl[0].z, 0);
+
+ Assert.AreEqual(Server.CurrentAbsoluteOrientation.Elevation, 0);
+ Assert.AreEqual(Server.CurrentAbsoluteOrientation.Azimuth, 0);
+ }
+
+ [TestMethod]
+ public void TestInterpretData_OnlyAzEncoder_InterpretsOnlyAzEncoder()
+ {
+ // Only the azimuth encoder is initialized
+ byte[] OnlyAzEnc = File.ReadAllBytes($"{TestPacketDirectory}OnlyAzEnc50.snp");
+
+ PrivateObject privServer = new PrivateObject(Server);
+
+ int expectedValue = 50;
+
+ // Call the function, which decodes the data
+ bool success = (bool)privServer.Invoke("InterpretData", OnlyAzEnc, OnlyAzEnc.Length);
+
+ Assert.IsTrue(success);
+
+ // Verify all of the values are as expected; converted values have a small margin of error
+ Assert.AreEqual(Server.CurrentElevationMotorTemp[0].temp, 0);
+ Assert.AreEqual(Server.CurrentAzimuthMotorTemp[0].temp, 0);
+
+ Assert.AreEqual(Server.CurrentElevationMotorAccl[0].x, 0);
+ Assert.AreEqual(Server.CurrentElevationMotorAccl[0].y, 0);
+ Assert.AreEqual(Server.CurrentElevationMotorAccl[0].z, 0);
+
+ Assert.AreEqual(Server.CurrentAzimuthMotorAccl[0].x, 0);
+ Assert.AreEqual(Server.CurrentAzimuthMotorAccl[0].y, 0);
+ Assert.AreEqual(Server.CurrentAzimuthMotorAccl[0].z, 0);
+
+ Assert.AreEqual(Server.CurrentCounterbalanceAccl[0].x, 0);
+ Assert.AreEqual(Server.CurrentCounterbalanceAccl[0].y, 0);
+ Assert.AreEqual(Server.CurrentCounterbalanceAccl[0].z, 0);
+
+ Assert.AreEqual(Server.CurrentAbsoluteOrientation.Elevation, 0);
+ Assert.AreEqual(Server.CurrentAbsoluteOrientation.Azimuth, 50, 0.17); // This should be the only populated value
+ }
+
+ [TestMethod]
+ public void TestInterpretData_OnlyElEncoder_InterpretsOnlyElEncoder()
+ {
+ // Only the elevation encoder is initialized
+ byte[] OnlyElEnc = File.ReadAllBytes($"{TestPacketDirectory}OnlyElEnc50.snp");
+
+ PrivateObject privServer = new PrivateObject(Server);
+
+ int expectedValue = 50;
+
+ // Call the function, which decodes the data
+ bool success = (bool)privServer.Invoke("InterpretData", OnlyElEnc, OnlyElEnc.Length);
+
+ Assert.IsTrue(success);
+
+ // Verify all of the values are as expected; converted values have a small margin of error
+ Assert.AreEqual(Server.CurrentElevationMotorTemp[0].temp, 0);
+ Assert.AreEqual(Server.CurrentAzimuthMotorTemp[0].temp, 0);
+
+ Assert.AreEqual(Server.CurrentElevationMotorAccl[0].x, 0);
+ Assert.AreEqual(Server.CurrentElevationMotorAccl[0].y, 0);
+ Assert.AreEqual(Server.CurrentElevationMotorAccl[0].z, 0);
+
+ Assert.AreEqual(Server.CurrentAzimuthMotorAccl[0].x, 0);
+ Assert.AreEqual(Server.CurrentAzimuthMotorAccl[0].y, 0);
+ Assert.AreEqual(Server.CurrentAzimuthMotorAccl[0].z, 0);
+
+ Assert.AreEqual(Server.CurrentCounterbalanceAccl[0].x, 0);
+ Assert.AreEqual(Server.CurrentCounterbalanceAccl[0].y, 0);
+ Assert.AreEqual(Server.CurrentCounterbalanceAccl[0].z, 0);
+
+ Assert.AreEqual(Server.CurrentAbsoluteOrientation.Elevation, 50, 0.17); // This should be the only populated value
+ Assert.AreEqual(Server.CurrentAbsoluteOrientation.Azimuth, 0);
+ }
+
+ [TestMethod]
+ public void TestInterpretData_OnlyElAccl_InterpretsOnlyElAccl()
+ {
+ // Only the elevation accelerometer is initialized
+ byte[] OnlyElAccl123 = File.ReadAllBytes($"{TestPacketDirectory}OnlyElAccl123.snp");
+
+ PrivateObject privServer = new PrivateObject(Server);
+
+ // Call the function, which decodes the data
+ bool success = (bool)privServer.Invoke("InterpretData", OnlyElAccl123, OnlyElAccl123.Length);
+
+ Assert.IsTrue(success);
+
+ // Verify all of the values are as expected; converted values have a small margin of error
+ Assert.AreEqual(Server.CurrentElevationMotorTemp[0].temp, 0);
+ Assert.AreEqual(Server.CurrentAzimuthMotorTemp[0].temp, 0);
+
+ // These should be the only populated values, based off of the pre-made
+ // packet I made for them
+ Assert.AreEqual(Server.CurrentElevationMotorAccl[0].x, 1);
+ Assert.AreEqual(Server.CurrentElevationMotorAccl[0].y, 2);
+ Assert.AreEqual(Server.CurrentElevationMotorAccl[0].z, 3);
+
+ Assert.AreEqual(Server.CurrentAzimuthMotorAccl[0].x, 0);
+ Assert.AreEqual(Server.CurrentAzimuthMotorAccl[0].y, 0);
+ Assert.AreEqual(Server.CurrentAzimuthMotorAccl[0].z, 0);
+
+ Assert.AreEqual(Server.CurrentCounterbalanceAccl[0].x, 0);
+ Assert.AreEqual(Server.CurrentCounterbalanceAccl[0].y, 0);
+ Assert.AreEqual(Server.CurrentCounterbalanceAccl[0].z, 0);
+
+ Assert.AreEqual(Server.CurrentAbsoluteOrientation.Elevation, 0);
+ Assert.AreEqual(Server.CurrentAbsoluteOrientation.Azimuth, 0);
+ }
+
+ [TestMethod]
+ public void TestInterpretData_OnlyAzAccl_InterpretsOnlyAzAccl()
+ {
+ // Only the azimuth accelerometer is initialized
+ byte[] OnlyAzAccl123 = File.ReadAllBytes($"{TestPacketDirectory}OnlyAzAccl123.snp");
+
+ PrivateObject privServer = new PrivateObject(Server);
+
+ // Call the function, which decodes the data
+ bool success = (bool)privServer.Invoke("InterpretData", OnlyAzAccl123, OnlyAzAccl123.Length);
+
+ Assert.IsTrue(success);
+
+ // Verify all of the values are as expected; converted values have a small margin of error
+ Assert.AreEqual(Server.CurrentElevationMotorTemp[0].temp, 0);
+ Assert.AreEqual(Server.CurrentAzimuthMotorTemp[0].temp, 0);
+
+ Assert.AreEqual(Server.CurrentElevationMotorAccl[0].x, 0);
+ Assert.AreEqual(Server.CurrentElevationMotorAccl[0].y, 0);
+ Assert.AreEqual(Server.CurrentElevationMotorAccl[0].z, 0);
+
+ // These should be the only populated values, based off of the pre-made
+ // packet I made for them
+ Assert.AreEqual(Server.CurrentAzimuthMotorAccl[0].x, 1);
+ Assert.AreEqual(Server.CurrentAzimuthMotorAccl[0].y, 2);
+ Assert.AreEqual(Server.CurrentAzimuthMotorAccl[0].z, 3);
+
+ Assert.AreEqual(Server.CurrentCounterbalanceAccl[0].x, 0);
+ Assert.AreEqual(Server.CurrentCounterbalanceAccl[0].y, 0);
+ Assert.AreEqual(Server.CurrentCounterbalanceAccl[0].z, 0);
+
+ Assert.AreEqual(Server.CurrentAbsoluteOrientation.Elevation, 0);
+ Assert.AreEqual(Server.CurrentAbsoluteOrientation.Azimuth, 0);
+ }
+
+ [TestMethod]
+ public void TestInterpretData_OnlyCbAccl_InterpretsOnlyCbAccl()
+ {
+ // Only the counterbalance accelerometer is initialized
+ byte[] OnlyCbAccl123 = File.ReadAllBytes($"{TestPacketDirectory}OnlyCbAccl123.snp");
+
+ PrivateObject privServer = new PrivateObject(Server);
+
+ // Call the function, which decodes the data
+ bool success = (bool)privServer.Invoke("InterpretData", OnlyCbAccl123, OnlyCbAccl123.Length);
+
+ Assert.IsTrue(success);
+
+ // Verify all of the values are as expected; converted values have a small margin of error
+ Assert.AreEqual(Server.CurrentElevationMotorTemp[0].temp, 0);
+ Assert.AreEqual(Server.CurrentAzimuthMotorTemp[0].temp, 0);
+
+ Assert.AreEqual(Server.CurrentElevationMotorAccl[0].x, 0);
+ Assert.AreEqual(Server.CurrentElevationMotorAccl[0].y, 0);
+ Assert.AreEqual(Server.CurrentElevationMotorAccl[0].z, 0);
+
+ Assert.AreEqual(Server.CurrentAzimuthMotorAccl[0].x, 0);
+ Assert.AreEqual(Server.CurrentAzimuthMotorAccl[0].y, 0);
+ Assert.AreEqual(Server.CurrentAzimuthMotorAccl[0].z, 0);
+
+ // These should be the only populated values, based off of the pre-made
+ // packet I made for them
+ Assert.AreEqual(Server.CurrentCounterbalanceAccl[0].x, 1);
+ Assert.AreEqual(Server.CurrentCounterbalanceAccl[0].y, 2);
+ Assert.AreEqual(Server.CurrentCounterbalanceAccl[0].z, 3);
+
+ Assert.AreEqual(Server.CurrentAbsoluteOrientation.Elevation, 0);
+ Assert.AreEqual(Server.CurrentAbsoluteOrientation.Azimuth, 0);
+ }
+
+ [TestMethod]
+ public void TestInterpretData_RequestInitialization_SendsCorrectInitialization()
+ {
+ PrivateObject privServer = new PrivateObject(Server);
+
+ byte[] result = new byte[0];
+
+ // We must create a separate thread for the simulated server to run on because we are
+ // expecting data from the client
+ Thread snServer = new Thread(() => {
+
+ // Start server using the client IP address because those values have to be the same
+ // in order for us to receive anything
+ TcpListener listener = new TcpListener(IPAddress.Parse(ClientIpAddress), ClientPort);
+ listener.Start();
+
+ // Create local client/stream to receive data
+ TcpClient localClient = listener.AcceptTcpClient();
+ NetworkStream stream = localClient.GetStream();
+
+ // This will hold our sensor initialization
+ byte[] bytes = new byte[SensorNetworkConstants.SensorNetworkSensorCount];
+
+ // Wait for initialization
+ stream.Read(bytes, 0, bytes.Length);
+
+ // If we reach here, we've received data
+ result = bytes;
+
+ localClient.Close();
+ localClient.Dispose();
+ stream.Close();
+ stream.Dispose();
+ listener.Stop();
+ });
+ snServer.Start();
+
+ // Prepare the config request
+ var packetToSend = Encoding.ASCII.GetBytes("Send Sensor Configuration");
+
+ // Call the function, will cause the initialization to be sent to the server
+ bool success = (bool)privServer.Invoke("InterpretData", packetToSend, packetToSend.Length);
+
+ snServer.Join();
+
+ Assert.IsTrue(success);
+
+ var expected = Server.InitializationClient.SensorNetworkConfig.GetSensorInitAsBytes();
+
+ // Verify that we received the sensor initialization that the client had
+ Assert.IsTrue(expected.SequenceEqual(result));
+
+ // Verify NO values get anything
+ Assert.AreEqual(Server.CurrentElevationMotorTemp[0].temp, 0);
+ Assert.AreEqual(Server.CurrentAzimuthMotorTemp[0].temp, 0);
+
+ Assert.AreEqual(Server.CurrentElevationMotorAccl[0].x, 0);
+ Assert.AreEqual(Server.CurrentElevationMotorAccl[0].y, 0);
+ Assert.AreEqual(Server.CurrentElevationMotorAccl[0].z, 0);
+
+ Assert.AreEqual(Server.CurrentAzimuthMotorAccl[0].x, 0);
+ Assert.AreEqual(Server.CurrentAzimuthMotorAccl[0].y, 0);
+ Assert.AreEqual(Server.CurrentAzimuthMotorAccl[0].z, 0);
+
+ Assert.AreEqual(Server.CurrentCounterbalanceAccl[0].x, 0);
+ Assert.AreEqual(Server.CurrentCounterbalanceAccl[0].y, 0);
+ Assert.AreEqual(Server.CurrentCounterbalanceAccl[0].z, 0);
+
+ Assert.AreEqual(Server.CurrentAbsoluteOrientation.Elevation, 0);
+ Assert.AreEqual(Server.CurrentAbsoluteOrientation.Azimuth, 0);
+ }
+
+ [TestMethod]
+ public void TestInterpretData_RequestInitializationFailed_StatusSetToInitFailed()
+ {
+ PrivateObject privServer = new PrivateObject(Server);
+
+ // Prepare the config request
+ var packetToSend = Encoding.ASCII.GetBytes("Send Sensor Configuration");
+
+ // Call the function, will cause the initialization to be sent to the server
+ bool success = (bool)privServer.Invoke("InterpretData", packetToSend, packetToSend.Length);
+
+ Assert.IsFalse(success);
+
+ // Check that the status is what we expect
+ Assert.AreEqual(Server.Status, SensorNetworkStatusEnum.InitializationSendingFailed);
+
+ // Verify NO values get anything
+ Assert.AreEqual(Server.CurrentElevationMotorTemp[0].temp, 0);
+ Assert.AreEqual(Server.CurrentAzimuthMotorTemp[0].temp, 0);
+
+ Assert.AreEqual(Server.CurrentElevationMotorAccl[0].x, 0);
+ Assert.AreEqual(Server.CurrentElevationMotorAccl[0].y, 0);
+ Assert.AreEqual(Server.CurrentElevationMotorAccl[0].z, 0);
+
+ Assert.AreEqual(Server.CurrentAzimuthMotorAccl[0].x, 0);
+ Assert.AreEqual(Server.CurrentAzimuthMotorAccl[0].y, 0);
+ Assert.AreEqual(Server.CurrentAzimuthMotorAccl[0].z, 0);
+
+ Assert.AreEqual(Server.CurrentCounterbalanceAccl[0].x, 0);
+ Assert.AreEqual(Server.CurrentCounterbalanceAccl[0].y, 0);
+ Assert.AreEqual(Server.CurrentCounterbalanceAccl[0].z, 0);
+
+ Assert.AreEqual(Server.CurrentAbsoluteOrientation.Elevation, 0);
+ Assert.AreEqual(Server.CurrentAbsoluteOrientation.Azimuth, 0);
+ }
+
+ [TestMethod]
+ public void TestInterpretData_WrongTransitId_StatusTransitIdError()
+ {
+ byte[] AnyPacket = File.ReadAllBytes($"{TestPacketDirectory}OnlyCbAccl123.snp");
+
+ PrivateObject privServer = new PrivateObject(Server);
+
+ // Set the transmit ID to something invalid
+ AnyPacket[0] = 5;
+
+ // Call the function, which decodes the data
+ bool success = (bool)privServer.Invoke("InterpretData", AnyPacket, AnyPacket.Length);
+
+ Assert.IsFalse(success);
+
+ // Verify the status is set to unknown error
+ Assert.AreEqual(Server.Status, SensorNetworkStatusEnum.TransitIdError);
+
+ // Verify all of the values are as expected; converted values have a small margin of error
+ Assert.AreEqual(Server.CurrentElevationMotorTemp[0].temp, 0);
+ Assert.AreEqual(Server.CurrentAzimuthMotorTemp[0].temp, 0);
+
+ Assert.AreEqual(Server.CurrentElevationMotorAccl[0].x, 0);
+ Assert.AreEqual(Server.CurrentElevationMotorAccl[0].y, 0);
+ Assert.AreEqual(Server.CurrentElevationMotorAccl[0].z, 0);
+
+ Assert.AreEqual(Server.CurrentAzimuthMotorAccl[0].x, 0);
+ Assert.AreEqual(Server.CurrentAzimuthMotorAccl[0].y, 0);
+ Assert.AreEqual(Server.CurrentAzimuthMotorAccl[0].z, 0);
+
+ Assert.AreEqual(Server.CurrentCounterbalanceAccl[0].x, 0);
+ Assert.AreEqual(Server.CurrentCounterbalanceAccl[0].y, 0);
+ Assert.AreEqual(Server.CurrentCounterbalanceAccl[0].z, 0);
+
+ Assert.AreEqual(Server.CurrentAbsoluteOrientation.Elevation, 0);
+ Assert.AreEqual(Server.CurrentAbsoluteOrientation.Azimuth, 0);
+ }
+
+ [TestMethod]
+ public void TestInterpretData_PacketSizeNotCorrect_Fail()
+ {
+ byte[] AnyPacket = File.ReadAllBytes($"{TestPacketDirectory}OnlyCbAccl123.snp");
+
+ PrivateObject privServer = new PrivateObject(Server);
+
+ // Change the inner packet size so it doesn't match the length of the byte array
+ AnyPacket[1] = 255;
+
+ // Call the function, which decodes the data
+ bool success = (bool)privServer.Invoke("InterpretData", AnyPacket, AnyPacket.Length);
+
+ Assert.IsFalse(success);
+
+ // Verify all of the values are as expected; converted values have a small margin of error
+ Assert.AreEqual(Server.CurrentElevationMotorTemp[0].temp, 0);
+ Assert.AreEqual(Server.CurrentAzimuthMotorTemp[0].temp, 0);
+
+ Assert.AreEqual(Server.CurrentElevationMotorAccl[0].x, 0);
+ Assert.AreEqual(Server.CurrentElevationMotorAccl[0].y, 0);
+ Assert.AreEqual(Server.CurrentElevationMotorAccl[0].z, 0);
+
+ Assert.AreEqual(Server.CurrentAzimuthMotorAccl[0].x, 0);
+ Assert.AreEqual(Server.CurrentAzimuthMotorAccl[0].y, 0);
+ Assert.AreEqual(Server.CurrentAzimuthMotorAccl[0].z, 0);
+
+ Assert.AreEqual(Server.CurrentCounterbalanceAccl[0].x, 0);
+ Assert.AreEqual(Server.CurrentCounterbalanceAccl[0].y, 0);
+ Assert.AreEqual(Server.CurrentCounterbalanceAccl[0].z, 0);
+
+ Assert.AreEqual(Server.CurrentAbsoluteOrientation.Elevation, 0);
+ Assert.AreEqual(Server.CurrentAbsoluteOrientation.Azimuth, 0);
+ }
+
+ [TestMethod]
+ public void TestTimedOut_StatusReceivingData_SetsToTimedOutReceivingData()
+ {
+ PrivateObject privServer = new PrivateObject(Server);
+
+ Server.Status = SensorNetworkStatusEnum.ReceivingData;
+
+ privServer.Invoke("TimedOut", new Object(), null);
+
+ Assert.AreEqual(SensorNetworkStatusEnum.TimedOutDataRetrieval, Server.Status);
+ }
+
+ [TestMethod]
+ public void TestTimedOut_StatusInitializing_SetsToTimedOutInitialization()
+ {
+ PrivateObject privServer = new PrivateObject(Server);
+
+ Server.Status = SensorNetworkStatusEnum.Initializing;
+
+ privServer.Invoke("TimedOut", new Object(), null);
+
+ Assert.AreEqual(SensorNetworkStatusEnum.TimedOutInitialization, Server.Status);
+ }
+
+ [TestMethod]
+ public void TestTimedOut_StatusNotInitializingOrReceivingData_SetsToServerError()
+ {
+ PrivateObject privServer = new PrivateObject(Server);
+
+ Server.Status = SensorNetworkStatusEnum.ServerError;
+
+ privServer.Invoke("TimedOut", new Object(), null);
+
+ Assert.AreEqual(SensorNetworkStatusEnum.UnknownError, Server.Status);
+ }
+
+ [TestMethod]
+ public void TestStartSensorMonitoringRoutine_RoutineStarts_AllValuesSet()
+ {
+ PrivateObject privServer = new PrivateObject(Server);
+
+ Server.StartSensorMonitoringRoutine();
+
+ // Retrieve any private fields
+ TcpListener resultServer = (TcpListener)privServer.GetFieldOrProperty("Server");
+ bool resultCurrentlyRunning = (bool)privServer.GetFieldOrProperty("CurrentlyRunning");
+ System.Timers.Timer resultTimer = (System.Timers.Timer)privServer.GetFieldOrProperty("Timeout");
+ Thread resultMonitorThread = (Thread)privServer.GetFieldOrProperty("SensorMonitoringThread");
+
+ // Verify all fields are as we expect them to be.
+ Assert.IsTrue(resultServer.Server.IsBound);
+
+ Assert.IsTrue(resultCurrentlyRunning);
+
+ Assert.AreEqual(SensorNetworkStatusEnum.Initializing, Server.Status);
+
+ Assert.AreEqual(SensorNetworkConstants.DefaultInitializationTimeout, resultTimer.Interval);
+ Assert.IsTrue(resultTimer.Enabled);
+
+ Assert.IsTrue(resultMonitorThread.IsAlive);
+
+ // Stop the monitoring routine. We aren't testing this, so no asserts are being checked here
+ Server.EndSensorMonitoringRoutine();
+ }
+
+ [TestMethod]
+ public void TestEndSensorMonitoringRoutine_RoutineEnds_AllValuesSet()
+ {
+ PrivateObject privServer = new PrivateObject(Server);
+
+ // Now this is the one we will not have any asserts for, because we are not testing it in this function
+ Server.StartSensorMonitoringRoutine();
+
+ Server.EndSensorMonitoringRoutine();
+
+ // Retrieve any private fields
+ TcpListener resultServer = (TcpListener)privServer.GetFieldOrProperty("Server");
+ bool resultCurrentlyRunning = (bool)privServer.GetFieldOrProperty("CurrentlyRunning");
+ System.Timers.Timer resultTimer = (System.Timers.Timer)privServer.GetFieldOrProperty("Timeout");
+ Thread resultMonitorThread = (Thread)privServer.GetFieldOrProperty("SensorMonitoringThread");
+
+ // Verify everything is brought down correctly (fields are as we expect them to be)
+ Assert.IsFalse(resultServer.Server.IsBound);
+
+ Assert.IsFalse(resultCurrentlyRunning);
+
+ Assert.IsFalse(resultMonitorThread.IsAlive);
+
+ Assert.AreEqual(SensorNetworkStatusEnum.None, Server.Status);
+
+ // Unfortunately, there is no good way to check if an object has been disposed, so we will just
+ // have to assume that the Timeout object is being disposed properly.
+
+ Assert.IsFalse(resultTimer.Enabled);
+ }
+
+ [TestMethod]
+ public void TestEndSensorMonitoringRoutine_RebootingFlagTrue_AllValuesSetWithRebootingStatus()
+ {
+ PrivateObject privServer = new PrivateObject(Server);
+
+ // Now this is the one we will not have any asserts for, because we are not testing it in this function
+ Server.StartSensorMonitoringRoutine();
+
+ Server.EndSensorMonitoringRoutine(true); // true represents it is "rebooting"
+
+ // Retrieve any private fields
+ TcpListener resultServer = (TcpListener)privServer.GetFieldOrProperty("Server");
+ bool resultCurrentlyRunning = (bool)privServer.GetFieldOrProperty("CurrentlyRunning");
+ System.Timers.Timer resultTimer = (System.Timers.Timer)privServer.GetFieldOrProperty("Timeout");
+ Thread resultMonitorThread = (Thread)privServer.GetFieldOrProperty("SensorMonitoringThread");
+
+ // Verify everything is brought down correctly (fields are as we expect them to be)
+ Assert.IsFalse(resultServer.Server.IsBound);
+
+ Assert.IsFalse(resultCurrentlyRunning);
+
+ Assert.IsFalse(resultMonitorThread.IsAlive);
+
+ Assert.AreEqual(SensorNetworkStatusEnum.Rebooting, Server.Status);
+
+ // Unfortunately, there is no good way to check if an object has been disposed, so we will just
+ // have to assume that the Timeout object is being disposed properly.
+
+ Assert.IsFalse(resultTimer.Enabled);
+ }
+
+ [TestMethod]
+ public void TestSensorMonitoringRoutine_InitializationTimeout_StatusInitializationTimeout()
+ {
+ Server.StartSensorMonitoringRoutine();
+
+ Thread.Sleep(SensorNetworkConstants.DefaultInitializationTimeout + 250);
+
+ Assert.AreEqual(SensorNetworkStatusEnum.TimedOutInitialization, Server.Status);
+
+ Server.EndSensorMonitoringRoutine();
+ }
+
+ [TestMethod]
+ public void TestSensorMonitoringRoutine_ReceivesFourPackets_StatusRetrievingData()
+ {
+ Server.StartSensorMonitoringRoutine();
+
+ // Prepare packets and client to send. We want two packets so we can alternate
+ // between them and verify data is being changed.
+ byte[] OnlyElEnc50 = File.ReadAllBytes($"{TestPacketDirectory}OnlyElEnc50.snp");
+ byte[] OnlyElEnc25 = File.ReadAllBytes($"{TestPacketDirectory}OnlyElEnc25.snp");
+ TcpClient sendToServer = new TcpClient(ServerIpAddress.ToString(), ServerPort);
+ NetworkStream stream = sendToServer.GetStream();
+
+ // First packet
+ stream.Write(OnlyElEnc50, 0, OnlyElEnc50.Length);
+ stream.Flush();
+
+ Thread.Sleep(25); // wait for data to be received
+
+ Assert.AreEqual(50, Server.CurrentAbsoluteOrientation.Elevation, 0.17);
+ Assert.AreEqual(SensorNetworkStatusEnum.ReceivingData, Server.Status);
+
+ Thread.Sleep(500);
+
+ // Second packet
+ stream.Write(OnlyElEnc25, 0, OnlyElEnc25.Length);
+ stream.Flush();
+
+ Thread.Sleep(25); // wait for data to be received
+
+ Assert.AreEqual(25, Server.CurrentAbsoluteOrientation.Elevation, 0.17);
+ Assert.AreEqual(SensorNetworkStatusEnum.ReceivingData, Server.Status);
+
+ Thread.Sleep(500);
+
+ // Third packet
+ stream.Write(OnlyElEnc50, 0, OnlyElEnc50.Length);
+ stream.Flush();
+
+ Thread.Sleep(25); // wait for data to be received
+
+ Assert.AreEqual(50, Server.CurrentAbsoluteOrientation.Elevation, 0.17);
+ Assert.AreEqual(SensorNetworkStatusEnum.ReceivingData, Server.Status);
+
+ Thread.Sleep(500);
+
+ // Last packet
+ stream.Write(OnlyElEnc25, 0, OnlyElEnc25.Length);
+ stream.Flush();
+
+ Thread.Sleep(25); // wait for data to be received
+
+ Assert.AreEqual(25, Server.CurrentAbsoluteOrientation.Elevation, 0.17);
+ Assert.AreEqual(SensorNetworkStatusEnum.ReceivingData, Server.Status);
+
+ // End everything
+ Server.EndSensorMonitoringRoutine();
+ stream.Close();
+ stream.Dispose();
+ sendToServer.Close();
+ sendToServer.Dispose();
+ }
+
+ [TestMethod]
+ public void TestSensorMonitoringRoutine_DataRetrievalTimeout_StatusDataRetrievalTimeout()
+ {
+ Server.StartSensorMonitoringRoutine();
+
+ // Prepare a single packet and client to send
+ byte[] OnlyElEnc = File.ReadAllBytes($"{TestPacketDirectory}OnlyElEnc50.snp");
+ TcpClient sendToServer = new TcpClient(ServerIpAddress.ToString(), ServerPort);
+ NetworkStream stream = sendToServer.GetStream();
+
+ // Send data to the Server
+ stream.Write(OnlyElEnc, 0, OnlyElEnc.Length);
+ stream.Flush();
+
+ // Wait for the data timeout, because it is waiting for a second packet now
+ Thread.Sleep(SensorNetworkConstants.DefaultDataRetrievalTimeout + 250);
+
+ Assert.AreEqual(SensorNetworkStatusEnum.TimedOutDataRetrieval, Server.Status);
+
+ // End everything
+ Server.EndSensorMonitoringRoutine();
+ stream.Close();
+ stream.Dispose();
+ sendToServer.Close();
+ sendToServer.Dispose();
+ }
+
+ [TestMethod]
+ public void TestSensorMonitoringRoutine_TimesOutThenReceivesPacket_StatusRetrievingData()
+ {
+ Server.StartSensorMonitoringRoutine();
+
+ // Prepare a single packet and client to send
+ byte[] OnlyElEnc = File.ReadAllBytes($"{TestPacketDirectory}OnlyElEnc50.snp");
+ byte[] OnlyElEnc25 = File.ReadAllBytes($"{TestPacketDirectory}OnlyElEnc25.snp");
+ TcpClient sendToServer = new TcpClient(ServerIpAddress.ToString(), ServerPort);
+ NetworkStream stream = sendToServer.GetStream();
+
+ // Send data to the Server
+ stream.Write(OnlyElEnc, 0, OnlyElEnc.Length);
+ stream.Flush();
+
+ // Wait for the data timeout, because it is waiting for a second packet now
+ Thread.Sleep(SensorNetworkConstants.DefaultDataRetrievalTimeout + 250);
+
+ Assert.AreEqual(SensorNetworkStatusEnum.TimedOutDataRetrieval, Server.Status);
+
+ // Now let's send another packet, which should change the status back to ReceivingData
+ stream.Write(OnlyElEnc25, 0, OnlyElEnc25.Length);
+ stream.Flush();
+
+ Thread.Sleep(25); // wait for data to be received
+
+ Assert.AreEqual(25, Server.CurrentAbsoluteOrientation.Elevation, 0.17);
+ Assert.AreEqual(SensorNetworkStatusEnum.ReceivingData, Server.Status);
+
+ // End everything
+ Server.EndSensorMonitoringRoutine();
+ stream.Close();
+ stream.Dispose();
+ sendToServer.Close();
+ sendToServer.Dispose();
+ }
+
+ [TestMethod]
+ public void TestRebootSensorNetwork_Reboots_AllFieldsSet()
+ {// These fields should be the same as the ones set in StartSensorMonitoringRoutine()
+ PrivateObject privServer = new PrivateObject(Server);
+ Server.StartSensorMonitoringRoutine();
+
+ Server.RebootSensorNetwork();
+
+ // Retrieve any private fields
+ TcpListener resultServer = (TcpListener)privServer.GetFieldOrProperty("Server");
+ bool resultCurrentlyRunning = (bool)privServer.GetFieldOrProperty("CurrentlyRunning");
+ System.Timers.Timer resultTimer = (System.Timers.Timer)privServer.GetFieldOrProperty("Timeout");
+ Thread resultMonitorThread = (Thread)privServer.GetFieldOrProperty("SensorMonitoringThread");
+
+ // Verify all fields are as we expect them to be.
+ Assert.IsTrue(resultServer.Server.IsBound);
+
+ Assert.IsTrue(resultCurrentlyRunning);
+
+ Assert.AreEqual(SensorNetworkStatusEnum.Initializing, Server.Status);
+
+ Assert.AreEqual(SensorNetworkConstants.DefaultInitializationTimeout, resultTimer.Interval);
+ Assert.IsTrue(resultTimer.Enabled);
+
+ Assert.IsTrue(resultMonitorThread.IsAlive);
+
+ // Stop the monitoring routine. We aren't testing this, so no asserts are being checked here
+ Server.EndSensorMonitoringRoutine();
+ }
+
+ [TestMethod]
+ public void TestRebootSensorNetwork_Reboots_CanStillReceivePackets()
+ {// These fields should be the same as the ones set in StartSensorMonitoringRoutine()
+ PrivateObject privServer = new PrivateObject(Server);
+ Server.StartSensorMonitoringRoutine();
+
+ Server.RebootSensorNetwork();
+
+ // Prepare packets and client to send. We want two packets so we can alternate
+ // between them and verify data is being changed.
+ byte[] OnlyElEnc50 = File.ReadAllBytes($"{TestPacketDirectory}OnlyElEnc50.snp");
+ byte[] OnlyElEnc25 = File.ReadAllBytes($"{TestPacketDirectory}OnlyElEnc25.snp");
+ TcpClient sendToServer = new TcpClient(ServerIpAddress.ToString(), ServerPort);
+ NetworkStream stream = sendToServer.GetStream();
+
+ // First packet
+ stream.Write(OnlyElEnc50, 0, OnlyElEnc50.Length);
+ stream.Flush();
+
+ Thread.Sleep(25); // wait for data to be received
+
+ Assert.AreEqual(50, Server.CurrentAbsoluteOrientation.Elevation, 0.17);
+ Assert.AreEqual(SensorNetworkStatusEnum.ReceivingData, Server.Status);
+
+ Thread.Sleep(500);
+
+ // Second packet
+ stream.Write(OnlyElEnc25, 0, OnlyElEnc25.Length);
+ stream.Flush();
+
+ Thread.Sleep(25); // wait for data to be received
+
+ Assert.AreEqual(25, Server.CurrentAbsoluteOrientation.Elevation, 0.17);
+ Assert.AreEqual(SensorNetworkStatusEnum.ReceivingData, Server.Status);
+
+ // Stop the monitoring routine. We aren't testing this, so no asserts are being checked here
+ Server.EndSensorMonitoringRoutine();
+ }
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/SensorNetworkTestPackets/AllData50.snp b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/SensorNetworkTestPackets/AllData50.snp
new file mode 100644
index 00000000..a1fa3d58
Binary files /dev/null and b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/SensorNetworkTestPackets/AllData50.snp differ
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/SensorNetworkTestPackets/OnlyAzAccl123.snp b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/SensorNetworkTestPackets/OnlyAzAccl123.snp
new file mode 100644
index 00000000..4165dda8
Binary files /dev/null and b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/SensorNetworkTestPackets/OnlyAzAccl123.snp differ
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/SensorNetworkTestPackets/OnlyAzEnc50.snp b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/SensorNetworkTestPackets/OnlyAzEnc50.snp
new file mode 100644
index 00000000..19a57ae4
Binary files /dev/null and b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/SensorNetworkTestPackets/OnlyAzEnc50.snp differ
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/SensorNetworkTestPackets/OnlyAzTemp50C.snp b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/SensorNetworkTestPackets/OnlyAzTemp50C.snp
new file mode 100644
index 00000000..e7bd0f91
Binary files /dev/null and b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/SensorNetworkTestPackets/OnlyAzTemp50C.snp differ
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/SensorNetworkTestPackets/OnlyCbAccl123.snp b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/SensorNetworkTestPackets/OnlyCbAccl123.snp
new file mode 100644
index 00000000..14022999
Binary files /dev/null and b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/SensorNetworkTestPackets/OnlyCbAccl123.snp differ
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/SensorNetworkTestPackets/OnlyElAccl123.snp b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/SensorNetworkTestPackets/OnlyElAccl123.snp
new file mode 100644
index 00000000..f430b942
Binary files /dev/null and b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/SensorNetworkTestPackets/OnlyElAccl123.snp differ
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/SensorNetworkTestPackets/OnlyElEnc25.snp b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/SensorNetworkTestPackets/OnlyElEnc25.snp
new file mode 100644
index 00000000..495e917a
Binary files /dev/null and b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/SensorNetworkTestPackets/OnlyElEnc25.snp differ
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/SensorNetworkTestPackets/OnlyElEnc50.snp b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/SensorNetworkTestPackets/OnlyElEnc50.snp
new file mode 100644
index 00000000..67a32a9e
Binary files /dev/null and b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/SensorNetworkTestPackets/OnlyElEnc50.snp differ
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/SensorNetworkTestPackets/OnlyElTemp50C.snp b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/SensorNetworkTestPackets/OnlyElTemp50C.snp
new file mode 100644
index 00000000..53b0b1ec
Binary files /dev/null and b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/SensorNetworkTestPackets/OnlyElTemp50C.snp differ
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/Simulation/PacketEncodingToolsTest.cs b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/Simulation/PacketEncodingToolsTest.cs
new file mode 100644
index 00000000..17243d86
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/Simulation/PacketEncodingToolsTest.cs
@@ -0,0 +1,307 @@
+using ControlRoomApplication.Controllers.SensorNetwork;
+using EmbeddedSystemsTest.SensorNetworkSimulation;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ControlRoomApplicationTest.EntityControllersTests.SensorNetworkTests.Simulation
+{
+ [TestClass]
+ public class PacketEncodingToolsTest
+ {
+ PacketEncodingTools tools = new PacketEncodingTools();
+
+ [TestMethod]
+ public void TestAdd64BitValueToByteArray_Max64BitUnsignedValue_ConvertsToByteArray()
+ {
+ ulong max = 0xFFFFFFFFFFFFFFFF;
+
+ byte[] resultBytes = new byte[8];
+ int counter = 0;
+
+ PacketEncodingTools.Add64BitValueToByteArray(ref resultBytes, ref counter, max);
+
+ // Create expected byte array
+ byte[] expectedBytes = new byte[8];
+ expectedBytes[0] = 255;
+ expectedBytes[1] = 255;
+ expectedBytes[2] = 255;
+ expectedBytes[3] = 255;
+ expectedBytes[4] = 255;
+ expectedBytes[5] = 255;
+ expectedBytes[6] = 255;
+ expectedBytes[7] = 255;
+
+ Assert.IsTrue(resultBytes.SequenceEqual(expectedBytes));
+ }
+
+ [TestMethod]
+ public void TestAdd64BitValueToByteArray_Min64BitUnsignedValue_ConvertsToByteArray()
+ {
+ ulong min = 0;
+
+ byte[] resultBytes = new byte[8];
+ int counter = 0;
+
+ PacketEncodingTools.Add64BitValueToByteArray(ref resultBytes, ref counter, min);
+
+ // Create expected byte array
+ byte[] expectedBytes = new byte[8];
+ expectedBytes[0] = 0;
+ expectedBytes[1] = 0;
+ expectedBytes[2] = 0;
+ expectedBytes[3] = 0;
+ expectedBytes[4] = 0;
+ expectedBytes[5] = 0;
+ expectedBytes[6] = 0;
+ expectedBytes[7] = 0;
+
+ Assert.IsTrue(resultBytes.SequenceEqual(expectedBytes));
+ }
+
+ [TestMethod]
+ public void TestAdd32BitValueToByteArray_Max32BitUnsignedValue_ConvertsToByteArray()
+ {
+ uint max = 4294967295;
+
+ byte[] resultBytes = new byte[4];
+ int counter = 0;
+
+ PacketEncodingTools.Add32BitValueToByteArray(ref resultBytes, ref counter, max);
+
+ // Create expected byte array
+ byte[] expectedBytes = new byte[4];
+ expectedBytes[0] = 255;
+ expectedBytes[1] = 255;
+ expectedBytes[2] = 255;
+ expectedBytes[3] = 255;
+
+ Assert.IsTrue(resultBytes.SequenceEqual(expectedBytes));
+ }
+
+ [TestMethod]
+ public void TestAdd32BitValueToByteArray_Min32BitUnsignedValue_ConvertsToByteArray()
+ {
+ uint min = 0;
+
+ byte[] resultBytes = new byte[4];
+ int counter = 0;
+
+ PacketEncodingTools.Add32BitValueToByteArray(ref resultBytes, ref counter, min);
+
+ // Create expected byte array
+ byte[] expectedBytes = new byte[4];
+ expectedBytes[0] = 0;
+ expectedBytes[1] = 0;
+ expectedBytes[2] = 0;
+ expectedBytes[3] = 0;
+
+ Assert.IsTrue(resultBytes.SequenceEqual(expectedBytes));
+ }
+
+ [TestMethod]
+ public void TestAdd16BitValueToByteArray_Max16BitUnsignedValue_ConvertsToByteArray()
+ {
+ short max = 32767;
+
+ byte[] resultBytes = new byte[2];
+ int counter = 0;
+
+ PacketEncodingTools.Add16BitValueToByteArray(ref resultBytes, ref counter, max);
+
+ // Create expected byte array
+ byte[] expectedBytes = new byte[2];
+ expectedBytes[0] = 127; // 127 because it is positive
+ expectedBytes[1] = 255;
+
+ Assert.IsTrue(resultBytes.SequenceEqual(expectedBytes));
+ }
+
+ [TestMethod]
+ public void TestAdd16BitValueToByteArray_Min16BitUnsignedValue_ConvertsToByteArray()
+ {
+ short min = -32768;
+
+ byte[] resultBytes = new byte[2];
+ int counter = 0;
+
+ PacketEncodingTools.Add16BitValueToByteArray(ref resultBytes, ref counter, min);
+
+ // Create expected byte array
+ byte[] expectedBytes = new byte[2];
+ expectedBytes[0] = 128;
+ expectedBytes[1] = 0;
+
+ Assert.IsTrue(resultBytes.SequenceEqual(expectedBytes));
+ }
+
+ [TestMethod]
+ public void TestConvertTempCToRawData_AnyDoubleData_MultipliesCorrectly()
+ {
+ double input = 1.1;
+
+ short result = PacketEncodingTools.ConvertTempCToRawData(input);
+
+ short expected = 17;
+
+ Assert.AreEqual(expected, result);
+ }
+
+ [TestMethod]
+ public void TestConvertDegreesToRawAzData_AnyDoubleData_CalculatesCorrectly()
+ {
+ double input = 1.1;
+
+ short result = PacketEncodingTools.ConvertDegreesToRawAzData(input);
+
+ short expected = (short)(SensorNetworkConstants.AzimuthEncoderScaling * input / 360 * -1);
+
+ Assert.AreEqual(expected, result);
+ }
+
+ [TestMethod]
+ public void TestConvertDegreesToRawElData_AnyDoubleData_CalculatesCorrectly()
+ {
+ double input = 1.1;
+
+ short result = PacketEncodingTools.ConvertDegreesToRawElData(input);
+
+ short expected = (short)Math.Round((input - 104.375) / -0.25);
+
+ Assert.AreEqual(expected, result);
+ }
+
+ [TestMethod]
+ public void TestCalcDataSize_AllZero_CalculatesSizeCorrectly()
+ {
+ uint result = PacketEncodingTools.CalcDataSize(0, 0, 0, 0, 0, 0, 0);
+
+ uint expected = 23; // Default data size with no sensors
+
+ Assert.AreEqual(expected, result);
+ }
+
+ [TestMethod]
+ public void TestCalcDataSize_ElAccelerometer_CalculatesSizeCorrectly()
+ {
+ int elAcc = 1; // 1 dump
+
+ uint result = PacketEncodingTools.CalcDataSize(elAcc, 0, 0, 0, 0, 0, 0);
+
+ uint expected = 23 + 6 + 8 + 2; // Default data size plus size of sensor data, timestamp, and FIFO length
+
+ Assert.AreEqual(expected, result);
+ }
+
+ [TestMethod]
+ public void TestCalcDataSize_AzAccelerometer_CalculatesSizeCorrectly()
+ {
+ int azAcc = 1; // 1 dump
+
+ uint result = PacketEncodingTools.CalcDataSize(0, azAcc, 0, 0, 0, 0, 0);
+
+ uint expected = 23 + 6 + 8 + 2; // Default data size plus size of sensor data, timestamp, and FIFO length
+
+ Assert.AreEqual(expected, result);
+ }
+
+ [TestMethod]
+ public void TestCalcDataSize_CbAccelerometer_CalculatesSizeCorrectly()
+ {
+ int cbAcc = 1; // 1 dump
+
+ uint result = PacketEncodingTools.CalcDataSize(0, 0, cbAcc, 0, 0, 0, 0);
+
+ uint expected = 23 + 6 + 8 + 2; // Default data size plus size of sensor data, timestamp, and FIFO length
+
+ Assert.AreEqual(expected, result);
+ }
+
+ [TestMethod]
+ public void TestCalcDataSize_ElTemperature_CalculatesSizeCorrectly()
+ {
+ int elTemp = 1; // 2 bytes
+
+ uint result = PacketEncodingTools.CalcDataSize(0, 0, 0, elTemp, 0, 0, 0);
+
+ uint expected = 23 + 2; // Default data size plus size of sensor data
+
+ Assert.AreEqual(expected, result);
+ }
+
+ [TestMethod]
+ public void TestCalcDataSize_AzTemperature_CalculatesSizeCorrectly()
+ {
+ int azTemp = 1; // 2 bytes
+
+ uint result = PacketEncodingTools.CalcDataSize(0, 0, 0, 0, azTemp, 0, 0);
+
+ uint expected = 23 + 2; // Default data size plus size of sensor data
+
+ Assert.AreEqual(expected, result);
+ }
+
+ [TestMethod]
+ public void TestCalcDataSize_ElEncoder_CalculatesSizeCorrectly()
+ {
+ int elEnc = 1; // 2 bytes
+
+ uint result = PacketEncodingTools.CalcDataSize(0, 0, 0, 0, 0, elEnc, 0);
+
+ uint expected = 23 + 2; // Default data size plus size of sensor data
+
+ Assert.AreEqual(expected, result);
+ }
+
+ [TestMethod]
+ public void TestCalcDataSize_AzEncoder_CalculatesSizeCorrectly()
+ {
+ int azEnc = 1; // 2 bytes
+
+ uint result = PacketEncodingTools.CalcDataSize(0, 0, 0, 0, 0, 0, azEnc);
+
+ uint expected = 23 + 2; // Default data size plus size of sensor data
+
+ Assert.AreEqual(expected, result);
+ }
+
+ [TestMethod]
+ public void TestConvertTempCToRawData_AnyNumber_MultipliesBy16()
+ {
+ double numToConvert = 3.56;
+
+ short expected = (short)(numToConvert * 16);
+
+ short result = PacketEncodingTools.ConvertTempCToRawData(numToConvert);
+
+ Assert.AreEqual(expected, result);
+ }
+
+ [TestMethod]
+ public void TestConvertDegreesToRawAzData_AnyNumber_FormulaCalculatesCorrectly()
+ {
+ double numToConvert = 3.56;
+
+ short expected = (short)(SensorNetworkConstants.AzimuthEncoderScaling * numToConvert / 360 * -1);
+
+ short result = PacketEncodingTools.ConvertDegreesToRawAzData(numToConvert);
+
+ Assert.AreEqual(expected, result);
+ }
+
+ [TestMethod]
+ public void TestConvertDegreesToRawElData_AnyNumber_FormulaCalculatesCorrectly()
+ {
+ double numToConvert = 3.56;
+
+ short expected = (short)Math.Round((numToConvert - 104.375) / -0.25);
+
+ short result = PacketEncodingTools.ConvertDegreesToRawElData(numToConvert);
+
+ Assert.AreEqual(expected, result);
+ }
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/Simulation/SimulationSensorNetworkTest.cs b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/Simulation/SimulationSensorNetworkTest.cs
new file mode 100644
index 00000000..6836b018
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/Simulation/SimulationSensorNetworkTest.cs
@@ -0,0 +1,1201 @@
+using ControlRoomApplication.Controllers.SensorNetwork;
+using ControlRoomApplication.Controllers.SensorNetwork.Simulation;
+using ControlRoomApplication.Database;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Net.Sockets;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace ControlRoomApplicationTest.EntityControllersTests.SensorNetworkTests.Simulation
+{
+ [TestClass]
+ public class SimulationSensorNetworkTest
+ {
+ string ClientIP = "127.0.0.1";
+ int ClientPort = 3000;
+
+ IPAddress ServerIP = IPAddress.Parse("127.0.0.2");
+ int ServerPort = 3001;
+
+ int TelescopeId = 3000;
+
+ string DataPath = "../../EntityControllersTests/SensorNetworkTests/Simulation/TestCSVData/";
+
+ SimulationSensorNetwork SimSensorNetwork;
+ PrivateObject PrivSim;
+
+ SensorNetworkServer SensorNetworkServer;
+ PrivateObject PrivServer;
+
+ [TestInitialize]
+ public void Initialize()
+ {
+ SimSensorNetwork = new SimulationSensorNetwork(ClientIP, ClientPort, ServerIP, ServerPort, DataPath);
+ PrivSim = new PrivateObject(SimSensorNetwork);
+
+ SensorNetworkServer = new SensorNetworkServer(IPAddress.Parse(ClientIP), ClientPort, ServerIP.ToString(), ServerPort, TelescopeId, false);
+ PrivServer = new PrivateObject(SensorNetworkServer);
+ }
+
+ [TestCleanup]
+ public void Cleanup()
+ {
+ DatabaseOperations.DeleteSensorNetworkConfig(SensorNetworkServer.InitializationClient.SensorNetworkConfig);
+ }
+
+ [TestMethod]
+ public void SimulationSensorNetwork_Constructor_AllFieldsCorrect()
+ {
+ // Gather data
+ TcpListener resultListener = (TcpListener)PrivSim.GetFieldOrProperty("Server");
+ string resultClientIP = (string)PrivSim.GetFieldOrProperty("ClientIP");
+ int resultClientPort = (int)PrivSim.GetFieldOrProperty("ClientPort");
+ string resultDataDirectory = (string)PrivSim.GetFieldOrProperty("DataDirectory");
+
+ // Verify server
+ Assert.IsNotNull(resultListener);
+ Assert.AreEqual(((IPEndPoint)resultListener.LocalEndpoint).Address, ServerIP);
+ Assert.AreEqual(((IPEndPoint)resultListener.LocalEndpoint).Port, ServerPort);
+
+ // Verify client
+ Assert.AreEqual(ClientIP, resultClientIP);
+ Assert.AreEqual(ClientPort, resultClientPort);
+
+ // Verify directory
+ Assert.AreEqual(DataPath, resultDataDirectory);
+ }
+
+ [TestMethod]
+ public void TestInitializeSensors_InitializeAllSensors_AllSensorsInitialized()
+ {
+ // Create an initialization that will enable all sensors.
+ byte[] init = new byte[9];
+ for(int i = 0; i < init.Length; i++) init[i] = 1;
+
+ PrivSim.Invoke("InitializeSensors", init);
+
+ // Gather result data
+ double[] resultElTemp = (double[])PrivSim.GetFieldOrProperty("ElevationTempData");
+ double[] resultAzTemp = (double[])PrivSim.GetFieldOrProperty("AzimuthTempData");
+ RawAccelerometerData[] resultElAcc = (RawAccelerometerData[])PrivSim.GetFieldOrProperty("ElevationAccData");
+ RawAccelerometerData[] resultAzAcc = (RawAccelerometerData[])PrivSim.GetFieldOrProperty("AzimuthAccData");
+ RawAccelerometerData[] resultCbAcc = (RawAccelerometerData[])PrivSim.GetFieldOrProperty("CounterbalanceAccData");
+ double[] resultElEnc = (double[])PrivSim.GetFieldOrProperty("ElevationEncoderData");
+ double[] resultAzEnc = (double[])PrivSim.GetFieldOrProperty("AzimuthEncoderData");
+
+ // Create expected array length (spoiler: it is zero)
+ int expectedArrLength = 0;
+
+ // Verify all arrays still have a length of 0
+ Assert.AreEqual(expectedArrLength, resultElTemp.Length);
+ Assert.AreEqual(expectedArrLength, resultAzTemp.Length);
+ Assert.AreEqual(expectedArrLength, resultElAcc.Length);
+ Assert.AreEqual(expectedArrLength, resultAzAcc.Length);
+ Assert.AreEqual(expectedArrLength, resultCbAcc.Length);
+ Assert.AreEqual(expectedArrLength, resultElEnc.Length);
+ Assert.AreEqual(expectedArrLength, resultAzEnc.Length);
+ }
+
+ [TestMethod]
+ public void TestInitializeSensors_DisableElTemp_OnlyElTempDisabled()
+ {
+ // Create an initialization that will enable all sensors.
+ byte[] init = new byte[SensorNetworkConstants.SensorNetworkSensorCount];
+
+ init[(int)SensorInitializationEnum.ElevationTemp] = 0;
+ init[(int)SensorInitializationEnum.AzimuthTemp] = 1;
+ init[(int)SensorInitializationEnum.ElevationEncoder] = 1;
+ init[(int)SensorInitializationEnum.AzimuthEncoder] = 1;
+ init[(int)SensorInitializationEnum.AzimuthAccelerometer] = 1;
+ init[(int)SensorInitializationEnum.ElevationAccelerometer] = 1;
+ init[(int)SensorInitializationEnum.CounterbalanceAccelerometer] = 1;
+
+ PrivSim.Invoke("InitializeSensors", init);
+
+ // Gather result data
+ double[] resultElTemp = (double[])PrivSim.GetFieldOrProperty("ElevationTempData");
+ double[] resultAzTemp = (double[])PrivSim.GetFieldOrProperty("AzimuthTempData");
+ RawAccelerometerData[] resultElAcc = (RawAccelerometerData[])PrivSim.GetFieldOrProperty("ElevationAccData");
+ RawAccelerometerData[] resultAzAcc = (RawAccelerometerData[])PrivSim.GetFieldOrProperty("AzimuthAccData");
+ RawAccelerometerData[] resultCbAcc = (RawAccelerometerData[])PrivSim.GetFieldOrProperty("CounterbalanceAccData");
+ double[] resultElEnc = (double[])PrivSim.GetFieldOrProperty("ElevationEncoderData");
+ double[] resultAzEnc = (double[])PrivSim.GetFieldOrProperty("AzimuthEncoderData");
+
+ // Create expected array length (spoiler: it is zero)
+ int expectedArrLength = 0;
+
+ // Verify all arrays still have a length of 0 except the null one
+ Assert.IsNull(resultElTemp);
+ Assert.AreEqual(expectedArrLength, resultAzTemp.Length);
+ Assert.AreEqual(expectedArrLength, resultElAcc.Length);
+ Assert.AreEqual(expectedArrLength, resultAzAcc.Length);
+ Assert.AreEqual(expectedArrLength, resultCbAcc.Length);
+ Assert.AreEqual(expectedArrLength, resultElEnc.Length);
+ Assert.AreEqual(expectedArrLength, resultAzEnc.Length);
+ }
+
+ [TestMethod]
+ public void TestInitializeSensors_DisableAzTemp_OnlyAzTempDisabled()
+ {
+ // Create an initialization that will enable all sensors.
+ byte[] init = new byte[SensorNetworkConstants.SensorNetworkSensorCount];
+
+ init[(int)SensorInitializationEnum.ElevationTemp] = 1;
+ init[(int)SensorInitializationEnum.AzimuthTemp] = 0;
+ init[(int)SensorInitializationEnum.ElevationEncoder] = 1;
+ init[(int)SensorInitializationEnum.AzimuthEncoder] = 1;
+ init[(int)SensorInitializationEnum.AzimuthAccelerometer] = 1;
+ init[(int)SensorInitializationEnum.ElevationAccelerometer] = 1;
+ init[(int)SensorInitializationEnum.CounterbalanceAccelerometer] = 1;
+
+ PrivSim.Invoke("InitializeSensors", init);
+
+ // Gather result data
+ double[] resultElTemp = (double[])PrivSim.GetFieldOrProperty("ElevationTempData");
+ double[] resultAzTemp = (double[])PrivSim.GetFieldOrProperty("AzimuthTempData");
+ RawAccelerometerData[] resultElAcc = (RawAccelerometerData[])PrivSim.GetFieldOrProperty("ElevationAccData");
+ RawAccelerometerData[] resultAzAcc = (RawAccelerometerData[])PrivSim.GetFieldOrProperty("AzimuthAccData");
+ RawAccelerometerData[] resultCbAcc = (RawAccelerometerData[])PrivSim.GetFieldOrProperty("CounterbalanceAccData");
+ double[] resultElEnc = (double[])PrivSim.GetFieldOrProperty("ElevationEncoderData");
+ double[] resultAzEnc = (double[])PrivSim.GetFieldOrProperty("AzimuthEncoderData");
+
+ // Create expected array length (spoiler: it is zero)
+ int expectedArrLength = 0;
+
+ // Verify all arrays still have a length of 0 except the null one
+ Assert.AreEqual(expectedArrLength, resultElTemp.Length);
+ Assert.IsNull(resultAzTemp);
+ Assert.AreEqual(expectedArrLength, resultElAcc.Length);
+ Assert.AreEqual(expectedArrLength, resultAzAcc.Length);
+ Assert.AreEqual(expectedArrLength, resultCbAcc.Length);
+ Assert.AreEqual(expectedArrLength, resultElEnc.Length);
+ Assert.AreEqual(expectedArrLength, resultAzEnc.Length);
+ }
+
+ [TestMethod]
+ public void TestInitializeSensors_DisableElEncoder_OnlyElEncoderDisabled()
+ {
+ // Create an initialization that will enable all sensors.
+ byte[] init = new byte[SensorNetworkConstants.SensorNetworkSensorCount];
+
+ init[(int)SensorInitializationEnum.ElevationTemp] = 1;
+ init[(int)SensorInitializationEnum.AzimuthTemp] = 1;
+ init[(int)SensorInitializationEnum.ElevationEncoder] = 0;
+ init[(int)SensorInitializationEnum.AzimuthEncoder] = 1;
+ init[(int)SensorInitializationEnum.AzimuthAccelerometer] = 1;
+ init[(int)SensorInitializationEnum.ElevationAccelerometer] = 1;
+ init[(int)SensorInitializationEnum.CounterbalanceAccelerometer] = 1;
+
+ PrivSim.Invoke("InitializeSensors", init);
+
+ // Gather result data
+ double[] resultElTemp = (double[])PrivSim.GetFieldOrProperty("ElevationTempData");
+ double[] resultAzTemp = (double[])PrivSim.GetFieldOrProperty("AzimuthTempData");
+ RawAccelerometerData[] resultElAcc = (RawAccelerometerData[])PrivSim.GetFieldOrProperty("ElevationAccData");
+ RawAccelerometerData[] resultAzAcc = (RawAccelerometerData[])PrivSim.GetFieldOrProperty("AzimuthAccData");
+ RawAccelerometerData[] resultCbAcc = (RawAccelerometerData[])PrivSim.GetFieldOrProperty("CounterbalanceAccData");
+ double[] resultElEnc = (double[])PrivSim.GetFieldOrProperty("ElevationEncoderData");
+ double[] resultAzEnc = (double[])PrivSim.GetFieldOrProperty("AzimuthEncoderData");
+
+ // Create expected array length (spoiler: it is zero)
+ int expectedArrLength = 0;
+
+ // Verify all arrays still have a length of 0 except the null one
+ Assert.AreEqual(expectedArrLength, resultElTemp.Length);
+ Assert.AreEqual(expectedArrLength, resultAzTemp.Length);
+ Assert.IsNull(resultElEnc);
+ Assert.AreEqual(expectedArrLength, resultAzEnc.Length);
+ Assert.AreEqual(expectedArrLength, resultElAcc.Length);
+ Assert.AreEqual(expectedArrLength, resultAzAcc.Length);
+ Assert.AreEqual(expectedArrLength, resultCbAcc.Length);
+ }
+
+ [TestMethod]
+ public void TestInitializeSensors_DisableAzEncoder_OnlyAzEncoderDisabled()
+ {
+ // Create an initialization that will enable all sensors.
+ byte[] init = new byte[SensorNetworkConstants.SensorNetworkSensorCount];
+
+ init[(int)SensorInitializationEnum.ElevationTemp] = 1;
+ init[(int)SensorInitializationEnum.AzimuthTemp] = 1;
+ init[(int)SensorInitializationEnum.ElevationEncoder] = 1;
+ init[(int)SensorInitializationEnum.AzimuthEncoder] = 0;
+ init[(int)SensorInitializationEnum.AzimuthAccelerometer] = 1;
+ init[(int)SensorInitializationEnum.ElevationAccelerometer] = 1;
+ init[(int)SensorInitializationEnum.CounterbalanceAccelerometer] = 1;
+
+ PrivSim.Invoke("InitializeSensors", init);
+
+ // Gather result data
+ double[] resultElTemp = (double[])PrivSim.GetFieldOrProperty("ElevationTempData");
+ double[] resultAzTemp = (double[])PrivSim.GetFieldOrProperty("AzimuthTempData");
+ RawAccelerometerData[] resultElAcc = (RawAccelerometerData[])PrivSim.GetFieldOrProperty("ElevationAccData");
+ RawAccelerometerData[] resultAzAcc = (RawAccelerometerData[])PrivSim.GetFieldOrProperty("AzimuthAccData");
+ RawAccelerometerData[] resultCbAcc = (RawAccelerometerData[])PrivSim.GetFieldOrProperty("CounterbalanceAccData");
+ double[] resultElEnc = (double[])PrivSim.GetFieldOrProperty("ElevationEncoderData");
+ double[] resultAzEnc = (double[])PrivSim.GetFieldOrProperty("AzimuthEncoderData");
+
+ // Create expected array length (spoiler: it is zero)
+ int expectedArrLength = 0;
+
+ // Verify all arrays still have a length of 0 except the null one
+ Assert.AreEqual(expectedArrLength, resultElTemp.Length);
+ Assert.AreEqual(expectedArrLength, resultAzTemp.Length);
+ Assert.AreEqual(expectedArrLength, resultElEnc.Length);
+ Assert.IsNull(resultAzEnc);
+ Assert.AreEqual(expectedArrLength, resultElAcc.Length);
+ Assert.AreEqual(expectedArrLength, resultAzAcc.Length);
+ Assert.AreEqual(expectedArrLength, resultCbAcc.Length);
+ }
+
+ [TestMethod]
+ public void TestInitializeSensors_DisableAzAcc_OnlyAzAccDisabled()
+ {
+ // Create an initialization that will enable all sensors.
+ byte[] init = new byte[SensorNetworkConstants.SensorNetworkSensorCount];
+
+ init[(int)SensorInitializationEnum.ElevationTemp] = 1;
+ init[(int)SensorInitializationEnum.AzimuthTemp] = 1;
+ init[(int)SensorInitializationEnum.ElevationEncoder] = 1;
+ init[(int)SensorInitializationEnum.AzimuthEncoder] = 1;
+ init[(int)SensorInitializationEnum.AzimuthAccelerometer] = 0;
+ init[(int)SensorInitializationEnum.ElevationAccelerometer] = 1;
+ init[(int)SensorInitializationEnum.CounterbalanceAccelerometer] = 1;
+
+ PrivSim.Invoke("InitializeSensors", init);
+
+ // Gather result data
+ double[] resultElTemp = (double[])PrivSim.GetFieldOrProperty("ElevationTempData");
+ double[] resultAzTemp = (double[])PrivSim.GetFieldOrProperty("AzimuthTempData");
+ RawAccelerometerData[] resultElAcc = (RawAccelerometerData[])PrivSim.GetFieldOrProperty("ElevationAccData");
+ RawAccelerometerData[] resultAzAcc = (RawAccelerometerData[])PrivSim.GetFieldOrProperty("AzimuthAccData");
+ RawAccelerometerData[] resultCbAcc = (RawAccelerometerData[])PrivSim.GetFieldOrProperty("CounterbalanceAccData");
+ double[] resultElEnc = (double[])PrivSim.GetFieldOrProperty("ElevationEncoderData");
+ double[] resultAzEnc = (double[])PrivSim.GetFieldOrProperty("AzimuthEncoderData");
+
+ // Create expected array length (spoiler: it is zero)
+ int expectedArrLength = 0;
+
+ // Verify all arrays still have a length of 0 except the null one
+ Assert.AreEqual(expectedArrLength, resultElTemp.Length);
+ Assert.AreEqual(expectedArrLength, resultAzTemp.Length);
+ Assert.AreEqual(expectedArrLength, resultElEnc.Length);
+ Assert.AreEqual(expectedArrLength, resultAzEnc.Length);
+ Assert.IsNull(resultAzAcc);
+ Assert.AreEqual(expectedArrLength, resultElAcc.Length);
+ Assert.AreEqual(expectedArrLength, resultCbAcc.Length);
+ }
+
+ [TestMethod]
+ public void TestInitializeSensors_DisableElAcc_OnlyElAccDisabled()
+ {
+ byte[] init = new byte[SensorNetworkConstants.SensorNetworkSensorCount];
+
+ init[(int)SensorInitializationEnum.ElevationTemp] = 1;
+ init[(int)SensorInitializationEnum.AzimuthTemp] = 1;
+ init[(int)SensorInitializationEnum.ElevationEncoder] = 1;
+ init[(int)SensorInitializationEnum.AzimuthEncoder] = 1;
+ init[(int)SensorInitializationEnum.AzimuthAccelerometer] = 1;
+ init[(int)SensorInitializationEnum.ElevationAccelerometer] = 0;
+ init[(int)SensorInitializationEnum.CounterbalanceAccelerometer] = 1;
+
+ PrivSim.Invoke("InitializeSensors", init);
+
+ // Gather result data
+ double[] resultElTemp = (double[])PrivSim.GetFieldOrProperty("ElevationTempData");
+ double[] resultAzTemp = (double[])PrivSim.GetFieldOrProperty("AzimuthTempData");
+ RawAccelerometerData[] resultElAcc = (RawAccelerometerData[])PrivSim.GetFieldOrProperty("ElevationAccData");
+ RawAccelerometerData[] resultAzAcc = (RawAccelerometerData[])PrivSim.GetFieldOrProperty("AzimuthAccData");
+ RawAccelerometerData[] resultCbAcc = (RawAccelerometerData[])PrivSim.GetFieldOrProperty("CounterbalanceAccData");
+ double[] resultElEnc = (double[])PrivSim.GetFieldOrProperty("ElevationEncoderData");
+ double[] resultAzEnc = (double[])PrivSim.GetFieldOrProperty("AzimuthEncoderData");
+
+ // Create expected array length (spoiler: it is zero)
+ int expectedArrLength = 0;
+
+ // Verify all arrays still have a length of 0 except the null one
+ Assert.AreEqual(expectedArrLength, resultElTemp.Length);
+ Assert.AreEqual(expectedArrLength, resultAzTemp.Length);
+ Assert.AreEqual(expectedArrLength, resultElEnc.Length);
+ Assert.AreEqual(expectedArrLength, resultAzEnc.Length);
+ Assert.AreEqual(expectedArrLength, resultAzAcc.Length);
+ Assert.IsNull(resultElAcc);
+ Assert.AreEqual(expectedArrLength, resultCbAcc.Length);
+ }
+
+ [TestMethod]
+ public void TestInitializeSensors_DisableCbAcc_OnlyCbAccDisabled()
+ {
+ byte[] init = new byte[SensorNetworkConstants.SensorNetworkSensorCount];
+
+ init[(int)SensorInitializationEnum.ElevationTemp] = 1;
+ init[(int)SensorInitializationEnum.AzimuthTemp] = 1;
+ init[(int)SensorInitializationEnum.ElevationEncoder] = 1;
+ init[(int)SensorInitializationEnum.AzimuthEncoder] = 1;
+ init[(int)SensorInitializationEnum.AzimuthAccelerometer] = 1;
+ init[(int)SensorInitializationEnum.ElevationAccelerometer] = 1;
+ init[(int)SensorInitializationEnum.CounterbalanceAccelerometer] = 0;
+
+ PrivSim.Invoke("InitializeSensors", init);
+
+ // Gather result data
+ double[] resultElTemp = (double[])PrivSim.GetFieldOrProperty("ElevationTempData");
+ double[] resultAzTemp = (double[])PrivSim.GetFieldOrProperty("AzimuthTempData");
+ RawAccelerometerData[] resultElAcc = (RawAccelerometerData[])PrivSim.GetFieldOrProperty("ElevationAccData");
+ RawAccelerometerData[] resultAzAcc = (RawAccelerometerData[])PrivSim.GetFieldOrProperty("AzimuthAccData");
+ RawAccelerometerData[] resultCbAcc = (RawAccelerometerData[])PrivSim.GetFieldOrProperty("CounterbalanceAccData");
+ double[] resultElEnc = (double[])PrivSim.GetFieldOrProperty("ElevationEncoderData");
+ double[] resultAzEnc = (double[])PrivSim.GetFieldOrProperty("AzimuthEncoderData");
+
+ // Create expected array length (spoiler: it is zero)
+ int expectedArrLength = 0;
+
+ // Verify all arrays still have a length of 0 except the null one
+ Assert.AreEqual(expectedArrLength, resultElTemp.Length);
+ Assert.AreEqual(expectedArrLength, resultAzTemp.Length);
+ Assert.AreEqual(expectedArrLength, resultElEnc.Length);
+ Assert.AreEqual(expectedArrLength, resultAzEnc.Length);
+ Assert.AreEqual(expectedArrLength, resultAzAcc.Length);
+ Assert.AreEqual(expectedArrLength, resultElAcc.Length);
+ Assert.IsNull(resultCbAcc);
+ }
+
+ [TestMethod]
+ public void TestInitializeSensors_DisableAllSensors_AllSensorsDisabled()
+ {
+ // Create an initialization
+ byte[] init = new byte[SensorNetworkConstants.SensorNetworkSensorCount];
+
+ init[(int)SensorInitializationEnum.ElevationTemp] = 0;
+ init[(int)SensorInitializationEnum.AzimuthTemp] = 0;
+ init[(int)SensorInitializationEnum.ElevationEncoder] = 0;
+ init[(int)SensorInitializationEnum.AzimuthEncoder] = 0;
+ init[(int)SensorInitializationEnum.AzimuthAccelerometer] = 0;
+ init[(int)SensorInitializationEnum.ElevationAccelerometer] = 0;
+ init[(int)SensorInitializationEnum.CounterbalanceAccelerometer] = 0;
+
+ PrivSim.Invoke("InitializeSensors", init);
+
+ // Gather result data
+ double[] resultElTemp = (double[])PrivSim.GetFieldOrProperty("ElevationTempData");
+ double[] resultAzTemp = (double[])PrivSim.GetFieldOrProperty("AzimuthTempData");
+ RawAccelerometerData[] resultElAcc = (RawAccelerometerData[])PrivSim.GetFieldOrProperty("ElevationAccData");
+ RawAccelerometerData[] resultAzAcc = (RawAccelerometerData[])PrivSim.GetFieldOrProperty("AzimuthAccData");
+ RawAccelerometerData[] resultCbAcc = (RawAccelerometerData[])PrivSim.GetFieldOrProperty("CounterbalanceAccData");
+ double[] resultElEnc = (double[])PrivSim.GetFieldOrProperty("ElevationEncoderData");
+ double[] resultAzEnc = (double[])PrivSim.GetFieldOrProperty("AzimuthEncoderData");
+
+ // Verify all arrays still have a length of 0 except the null one
+ Assert.IsNull(resultElTemp);
+ Assert.IsNull(resultAzTemp);
+ Assert.IsNull(resultElEnc);
+ Assert.IsNull(resultAzEnc);
+ Assert.IsNull(resultAzAcc);
+ Assert.IsNull(resultElAcc);
+ Assert.IsNull(resultCbAcc);
+ }
+
+ [TestMethod]
+ public void TestReadFakeDataFromCSV_ElTemp_ElTempsAreCorrect()
+ {
+ // Initialize only one sensor, so that is the only sensor that gets CSV data.
+ byte[] init = new byte[SensorNetworkConstants.SensorNetworkSensorCount];
+
+ init[(int)SensorInitializationEnum.ElevationTemp] = 1;
+ init[(int)SensorInitializationEnum.AzimuthTemp] = 0;
+ init[(int)SensorInitializationEnum.ElevationEncoder] = 0;
+ init[(int)SensorInitializationEnum.AzimuthEncoder] = 0;
+ init[(int)SensorInitializationEnum.AzimuthAccelerometer] = 0;
+ init[(int)SensorInitializationEnum.ElevationAccelerometer] = 0;
+ init[(int)SensorInitializationEnum.CounterbalanceAccelerometer] = 0;
+
+ PrivSim.Invoke("InitializeSensors", init);
+
+ PrivSim.Invoke("ReadFakeDataFromCSV");
+
+ // Gather result data
+ double[] resultElTemp = (double[])PrivSim.GetFieldOrProperty("ElevationTempData");
+ double[] resultAzTemp = (double[])PrivSim.GetFieldOrProperty("AzimuthTempData");
+ RawAccelerometerData[] resultElAcc = (RawAccelerometerData[])PrivSim.GetFieldOrProperty("ElevationAccData");
+ RawAccelerometerData[] resultAzAcc = (RawAccelerometerData[])PrivSim.GetFieldOrProperty("AzimuthAccData");
+ RawAccelerometerData[] resultCbAcc = (RawAccelerometerData[])PrivSim.GetFieldOrProperty("CounterbalanceAccData");
+ double[] resultElEnc = (double[])PrivSim.GetFieldOrProperty("ElevationEncoderData");
+ double[] resultAzEnc = (double[])PrivSim.GetFieldOrProperty("AzimuthEncoderData");
+
+ double[] expectedArray = new double[] { 1, 2 };
+
+ // Verify the result array is as expected
+ Assert.IsTrue(expectedArray.SequenceEqual(resultElTemp));
+
+ // Verify the rest of the fields are still null
+ Assert.IsNull(resultAzTemp);
+ Assert.IsNull(resultElEnc);
+ Assert.IsNull(resultAzEnc);
+ Assert.IsNull(resultAzAcc);
+ Assert.IsNull(resultElAcc);
+ Assert.IsNull(resultCbAcc);
+ }
+
+ [TestMethod]
+ public void TestReadFakeDataFromCSV_AzTemp_AzTempsAreCorrect()
+ {
+ // Initialize only one sensor, so that is the only sensor that gets CSV data.
+ byte[] init = new byte[SensorNetworkConstants.SensorNetworkSensorCount];
+
+ init[(int)SensorInitializationEnum.ElevationTemp] = 0;
+ init[(int)SensorInitializationEnum.AzimuthTemp] = 1;
+ init[(int)SensorInitializationEnum.ElevationEncoder] = 0;
+ init[(int)SensorInitializationEnum.AzimuthEncoder] = 0;
+ init[(int)SensorInitializationEnum.AzimuthAccelerometer] = 0;
+ init[(int)SensorInitializationEnum.ElevationAccelerometer] = 0;
+ init[(int)SensorInitializationEnum.CounterbalanceAccelerometer] = 0;
+
+ PrivSim.Invoke("InitializeSensors", init);
+
+ PrivSim.Invoke("ReadFakeDataFromCSV");
+
+ // Gather result data
+ double[] resultElTemp = (double[])PrivSim.GetFieldOrProperty("ElevationTempData");
+ double[] resultAzTemp = (double[])PrivSim.GetFieldOrProperty("AzimuthTempData");
+ RawAccelerometerData[] resultElAcc = (RawAccelerometerData[])PrivSim.GetFieldOrProperty("ElevationAccData");
+ RawAccelerometerData[] resultAzAcc = (RawAccelerometerData[])PrivSim.GetFieldOrProperty("AzimuthAccData");
+ RawAccelerometerData[] resultCbAcc = (RawAccelerometerData[])PrivSim.GetFieldOrProperty("CounterbalanceAccData");
+ double[] resultElEnc = (double[])PrivSim.GetFieldOrProperty("ElevationEncoderData");
+ double[] resultAzEnc = (double[])PrivSim.GetFieldOrProperty("AzimuthEncoderData");
+
+ double[] expectedArray = new double[] { 2, 3 };
+
+ // Verify the result array is as expected
+ Assert.IsTrue(expectedArray.SequenceEqual(resultAzTemp));
+
+ // Verify the rest of the fields are still null
+ Assert.IsNull(resultElTemp);
+ Assert.IsNull(resultElEnc);
+ Assert.IsNull(resultAzEnc);
+ Assert.IsNull(resultAzAcc);
+ Assert.IsNull(resultElAcc);
+ Assert.IsNull(resultCbAcc);
+ }
+
+ [TestMethod]
+ public void TestReadFakeDataFromCSV_ElEnc_ElEncPosAreCorrect()
+ {
+ // Initialize only one sensor, so that is the only sensor that gets CSV data.
+ byte[] init = new byte[SensorNetworkConstants.SensorNetworkSensorCount];
+
+ init[(int)SensorInitializationEnum.ElevationTemp] = 0;
+ init[(int)SensorInitializationEnum.AzimuthTemp] = 0;
+ init[(int)SensorInitializationEnum.ElevationEncoder] = 1;
+ init[(int)SensorInitializationEnum.AzimuthEncoder] = 0;
+ init[(int)SensorInitializationEnum.AzimuthAccelerometer] = 0;
+ init[(int)SensorInitializationEnum.ElevationAccelerometer] = 0;
+ init[(int)SensorInitializationEnum.CounterbalanceAccelerometer] = 0;
+
+ PrivSim.Invoke("InitializeSensors", init);
+
+ PrivSim.Invoke("ReadFakeDataFromCSV");
+
+ // Gather result data
+ double[] resultElTemp = (double[])PrivSim.GetFieldOrProperty("ElevationTempData");
+ double[] resultAzTemp = (double[])PrivSim.GetFieldOrProperty("AzimuthTempData");
+ RawAccelerometerData[] resultElAcc = (RawAccelerometerData[])PrivSim.GetFieldOrProperty("ElevationAccData");
+ RawAccelerometerData[] resultAzAcc = (RawAccelerometerData[])PrivSim.GetFieldOrProperty("AzimuthAccData");
+ RawAccelerometerData[] resultCbAcc = (RawAccelerometerData[])PrivSim.GetFieldOrProperty("CounterbalanceAccData");
+ double[] resultElEnc = (double[])PrivSim.GetFieldOrProperty("ElevationEncoderData");
+ double[] resultAzEnc = (double[])PrivSim.GetFieldOrProperty("AzimuthEncoderData");
+
+ double[] expectedArray = new double[] { 3, 4 };
+
+ // Verify the result array is as expected
+ Assert.IsTrue(expectedArray.SequenceEqual(resultElEnc));
+
+ // Verify the rest of the fields are still null
+ Assert.IsNull(resultElTemp);
+ Assert.IsNull(resultAzTemp);
+ Assert.IsNull(resultAzEnc);
+ Assert.IsNull(resultAzAcc);
+ Assert.IsNull(resultElAcc);
+ Assert.IsNull(resultCbAcc);
+ }
+
+ [TestMethod]
+ public void TestReadFakeDataFromCSV_AzEnc_AzEncPosAreCorrect()
+ {
+ // Initialize only one sensor, so that is the only sensor that gets CSV data.
+ byte[] init = new byte[SensorNetworkConstants.SensorNetworkSensorCount];
+
+ init[(int)SensorInitializationEnum.ElevationTemp] = 0;
+ init[(int)SensorInitializationEnum.AzimuthTemp] = 0;
+ init[(int)SensorInitializationEnum.ElevationEncoder] = 0;
+ init[(int)SensorInitializationEnum.AzimuthEncoder] = 1;
+ init[(int)SensorInitializationEnum.AzimuthAccelerometer] = 0;
+ init[(int)SensorInitializationEnum.ElevationAccelerometer] = 0;
+ init[(int)SensorInitializationEnum.CounterbalanceAccelerometer] = 0;
+
+ PrivSim.Invoke("InitializeSensors", init);
+
+ PrivSim.Invoke("ReadFakeDataFromCSV");
+
+ // Gather result data
+ double[] resultElTemp = (double[])PrivSim.GetFieldOrProperty("ElevationTempData");
+ double[] resultAzTemp = (double[])PrivSim.GetFieldOrProperty("AzimuthTempData");
+ RawAccelerometerData[] resultElAcc = (RawAccelerometerData[])PrivSim.GetFieldOrProperty("ElevationAccData");
+ RawAccelerometerData[] resultAzAcc = (RawAccelerometerData[])PrivSim.GetFieldOrProperty("AzimuthAccData");
+ RawAccelerometerData[] resultCbAcc = (RawAccelerometerData[])PrivSim.GetFieldOrProperty("CounterbalanceAccData");
+ double[] resultElEnc = (double[])PrivSim.GetFieldOrProperty("ElevationEncoderData");
+ double[] resultAzEnc = (double[])PrivSim.GetFieldOrProperty("AzimuthEncoderData");
+
+ double[] expectedArray = new double[] { 4, 5 };
+
+ // Verify the result array is as expected
+ Assert.IsTrue(expectedArray.SequenceEqual(resultAzEnc));
+
+ // Verify the rest of the fields are still null
+ Assert.IsNull(resultElTemp);
+ Assert.IsNull(resultAzTemp);
+ Assert.IsNull(resultElEnc);
+ Assert.IsNull(resultAzAcc);
+ Assert.IsNull(resultElAcc);
+ Assert.IsNull(resultCbAcc);
+ }
+
+ [TestMethod]
+ public void TestReadFakeDataFromCSV_AzAcc_AzAccAreCorrect()
+ {
+ byte[] init = new byte[SensorNetworkConstants.SensorNetworkSensorCount];
+
+ init[(int)SensorInitializationEnum.ElevationTemp] = 0;
+ init[(int)SensorInitializationEnum.AzimuthTemp] = 0;
+ init[(int)SensorInitializationEnum.ElevationEncoder] = 0;
+ init[(int)SensorInitializationEnum.AzimuthEncoder] = 0;
+ init[(int)SensorInitializationEnum.AzimuthAccelerometer] = 1;
+ init[(int)SensorInitializationEnum.ElevationAccelerometer] = 0;
+ init[(int)SensorInitializationEnum.CounterbalanceAccelerometer] = 0;
+
+ PrivSim.Invoke("InitializeSensors", init);
+
+ PrivSim.Invoke("ReadFakeDataFromCSV");
+
+ // Gather result data
+ double[] resultElTemp = (double[])PrivSim.GetFieldOrProperty("ElevationTempData");
+ double[] resultAzTemp = (double[])PrivSim.GetFieldOrProperty("AzimuthTempData");
+ RawAccelerometerData[] resultElAcc = (RawAccelerometerData[])PrivSim.GetFieldOrProperty("ElevationAccData");
+ RawAccelerometerData[] resultAzAcc = (RawAccelerometerData[])PrivSim.GetFieldOrProperty("AzimuthAccData");
+ RawAccelerometerData[] resultCbAcc = (RawAccelerometerData[])PrivSim.GetFieldOrProperty("CounterbalanceAccData");
+ double[] resultElEnc = (double[])PrivSim.GetFieldOrProperty("ElevationEncoderData");
+ double[] resultAzEnc = (double[])PrivSim.GetFieldOrProperty("AzimuthEncoderData");
+
+ RawAccelerometerData[] expectedAcc = new RawAccelerometerData[400];
+
+ for (int i = 0; i < 400; i++)
+ {
+ if (i <= 199)
+ {
+ expectedAcc[i].X = 6;
+ expectedAcc[i].Y = 13;
+ expectedAcc[i].Z = 11;
+ }
+ else
+ {
+ expectedAcc[i].X = 5;
+ expectedAcc[i].Y = 12;
+ expectedAcc[i].Z = 10;
+ }
+ }
+
+ // Verify the result array is as expected
+ Assert.IsTrue(expectedAcc.SequenceEqual(resultAzAcc));
+
+ // Verify the rest of the fields are still null
+ Assert.IsNull(resultElTemp);
+ Assert.IsNull(resultAzTemp);
+ Assert.IsNull(resultElEnc);
+ Assert.IsNull(resultAzEnc);
+ Assert.IsNull(resultElAcc);
+ Assert.IsNull(resultCbAcc);
+ }
+
+ [TestMethod]
+ public void TestReadFakeDataFromCSV_ElAcc_ElAccAreCorrect()
+ {
+ byte[] init = new byte[SensorNetworkConstants.SensorNetworkSensorCount];
+
+ init[(int)SensorInitializationEnum.ElevationTemp] = 0;
+ init[(int)SensorInitializationEnum.AzimuthTemp] = 0;
+ init[(int)SensorInitializationEnum.ElevationEncoder] = 0;
+ init[(int)SensorInitializationEnum.AzimuthEncoder] = 0;
+ init[(int)SensorInitializationEnum.AzimuthAccelerometer] = 0;
+ init[(int)SensorInitializationEnum.ElevationAccelerometer] = 1;
+ init[(int)SensorInitializationEnum.CounterbalanceAccelerometer] = 0;
+
+ PrivSim.Invoke("InitializeSensors", init);
+
+ PrivSim.Invoke("ReadFakeDataFromCSV");
+
+ // Gather result data
+ double[] resultElTemp = (double[])PrivSim.GetFieldOrProperty("ElevationTempData");
+ double[] resultAzTemp = (double[])PrivSim.GetFieldOrProperty("AzimuthTempData");
+ RawAccelerometerData[] resultElAcc = (RawAccelerometerData[])PrivSim.GetFieldOrProperty("ElevationAccData");
+ RawAccelerometerData[] resultAzAcc = (RawAccelerometerData[])PrivSim.GetFieldOrProperty("AzimuthAccData");
+ RawAccelerometerData[] resultCbAcc = (RawAccelerometerData[])PrivSim.GetFieldOrProperty("CounterbalanceAccData");
+ double[] resultElEnc = (double[])PrivSim.GetFieldOrProperty("ElevationEncoderData");
+ double[] resultAzEnc = (double[])PrivSim.GetFieldOrProperty("AzimuthEncoderData");
+
+ RawAccelerometerData[] expectedAcc = new RawAccelerometerData[400];
+
+ for (int i = 0; i < 400; i++)
+ {
+ if (i <= 199)
+ {
+ expectedAcc[i].X = 6;
+ expectedAcc[i].Y = 13;
+ expectedAcc[i].Z = 11;
+ }
+ else
+ {
+ expectedAcc[i].X = 5;
+ expectedAcc[i].Y = 12;
+ expectedAcc[i].Z = 10;
+ }
+ }
+
+ // Verify the result array is as expected
+ Assert.IsTrue(expectedAcc.SequenceEqual(resultElAcc));
+
+ // Verify the rest of the fields are still null
+ Assert.IsNull(resultElTemp);
+ Assert.IsNull(resultAzTemp);
+ Assert.IsNull(resultElEnc);
+ Assert.IsNull(resultAzEnc);
+ Assert.IsNull(resultAzAcc);
+ Assert.IsNull(resultCbAcc);
+ }
+
+ [TestMethod]
+ public void TestReadFakeDataFromCSV_CbAcc_CbAccAreCorrect()
+ {
+ byte[] init = new byte[SensorNetworkConstants.SensorNetworkSensorCount];
+
+ init[(int)SensorInitializationEnum.ElevationTemp] = 0;
+ init[(int)SensorInitializationEnum.AzimuthTemp] = 0;
+ init[(int)SensorInitializationEnum.ElevationEncoder] = 0;
+ init[(int)SensorInitializationEnum.AzimuthEncoder] = 0;
+ init[(int)SensorInitializationEnum.AzimuthAccelerometer] = 0;
+ init[(int)SensorInitializationEnum.ElevationAccelerometer] = 0;
+ init[(int)SensorInitializationEnum.CounterbalanceAccelerometer] = 1;
+
+ PrivSim.Invoke("InitializeSensors", init);
+
+ PrivSim.Invoke("ReadFakeDataFromCSV");
+
+ // Gather result data
+ double[] resultElTemp = (double[])PrivSim.GetFieldOrProperty("ElevationTempData");
+ double[] resultAzTemp = (double[])PrivSim.GetFieldOrProperty("AzimuthTempData");
+ RawAccelerometerData[] resultElAcc = (RawAccelerometerData[])PrivSim.GetFieldOrProperty("ElevationAccData");
+ RawAccelerometerData[] resultAzAcc = (RawAccelerometerData[])PrivSim.GetFieldOrProperty("AzimuthAccData");
+ RawAccelerometerData[] resultCbAcc = (RawAccelerometerData[])PrivSim.GetFieldOrProperty("CounterbalanceAccData");
+ double[] resultElEnc = (double[])PrivSim.GetFieldOrProperty("ElevationEncoderData");
+ double[] resultAzEnc = (double[])PrivSim.GetFieldOrProperty("AzimuthEncoderData");
+
+ RawAccelerometerData[] expectedAcc = new RawAccelerometerData[400];
+
+ for (int i = 0; i < 400; i++)
+ {
+ if (i <= 199)
+ {
+ expectedAcc[i].X = 6;
+ expectedAcc[i].Y = 13;
+ expectedAcc[i].Z = 11;
+ }
+ else
+ {
+ expectedAcc[i].X = 5;
+ expectedAcc[i].Y = 12;
+ expectedAcc[i].Z = 10;
+ }
+ }
+
+ // Verify the result array is as expected
+ Assert.IsTrue(expectedAcc.SequenceEqual(resultCbAcc));
+
+ // Verify the rest of the fields are still null
+ Assert.IsNull(resultElTemp);
+ Assert.IsNull(resultAzTemp);
+ Assert.IsNull(resultElEnc);
+ Assert.IsNull(resultAzEnc);
+ Assert.IsNull(resultAzAcc);
+ Assert.IsNull(resultElAcc);
+ }
+
+ [TestMethod]
+ public void TestWaitForAndConnectToServer_ConnectToServer_AsksForConfiguration()
+ {
+ // Must be currently running to do this
+ PrivSim.SetFieldOrProperty("CurrentlyRunning", true);
+
+ byte[] expected = Encoding.ASCII.GetBytes("Send Sensor Configuration");
+ byte[] result = new byte[expected.Length];
+
+ // First create server that expects the "Send Sensor Configuration" message
+ Thread expectConfThread = new Thread(() =>
+ {
+ TcpListener confListen = new TcpListener(IPAddress.Parse(ClientIP), ClientPort);
+ confListen.Start();
+
+ NetworkStream confStream;
+ TcpClient localClient = confListen.AcceptTcpClient();
+
+ confStream = localClient.GetStream();
+ confStream.Read(result, 0, expected.Length);
+
+ confListen.Stop();
+ confStream.Close();
+ confStream.Dispose();
+ });
+ expectConfThread.Start();
+
+ // This method has a blocking method, so we must run it in a separate thread
+ Thread serverThread = new Thread(() => {
+ // Set up client on the simulation
+ PrivSim.Invoke("WaitForAndConnectToServer");
+ });
+ serverThread.Start();
+
+ expectConfThread.Join();
+
+ // Stop the server in the simulation
+ ((TcpListener)PrivSim.GetFieldOrProperty("Server")).Stop();
+ serverThread.Join();
+
+ Assert.IsTrue(expected.SequenceEqual(result));
+ }
+
+ [TestMethod]
+ public void TestRequestAndAcquireSensorInitialization_SendsConfiguration_ReceiveCorrectBytes()
+ {
+ // Must be currently running to do this
+ PrivSim.SetFieldOrProperty("CurrentlyRunning", true);
+
+ // First create server that expects the "Send Sensor Configuration" message
+ // This only takes in the first
+ Thread expectConfThread = new Thread(() =>
+ {
+
+ TcpListener confListen = new TcpListener(IPAddress.Parse(ClientIP), ClientPort);
+ confListen.Start();
+
+ NetworkStream confStream;
+ TcpClient localClient = confListen.AcceptTcpClient();
+
+ byte[] dontCareVal = new byte[1];
+
+ confStream = localClient.GetStream();
+ confStream.Read(dontCareVal, 0, dontCareVal.Length);
+
+ confListen.Stop();
+ confStream.Close();
+ confStream.Dispose();
+ });
+ expectConfThread.Start();
+
+ byte[] expected = Encoding.ASCII.GetBytes("1234567");
+ byte[] result = new byte[expected.Length];
+
+ // This method has a blocking method, so we must run it in a separate thread
+ Thread serverThread = new Thread(() => {
+
+ // Set up client on the simulation
+ PrivSim.Invoke("WaitForAndConnectToServer");
+
+ result = (byte[])PrivSim.Invoke("RequestAndAcquireSensorInitialization");
+ });
+ serverThread.Start();
+
+ expectConfThread.Join();
+
+ // Create a client to send something to the server
+ // We are using the server IP and port because these must be the same
+ // between client/server in order to transmit data
+ TcpClient client = new TcpClient(ServerIP.ToString(), ServerPort);
+ NetworkStream stream = client.GetStream();
+ stream.Write(expected, 0, expected.Length);
+
+ //stream.Write(expected, 0, expected.Length);
+ stream.Flush();
+
+ // Dispose client and end thread
+ serverThread.Join();
+ stream.Close();
+ stream.Dispose();
+ client.Close();
+ client.Dispose();
+
+ Assert.IsTrue(expected.SequenceEqual(result));
+ }
+
+ [TestMethod]
+ public void TestStartSimulationSensorNetwork_Starts_AllObjectsAsExpected()
+ {
+ SimSensorNetwork.StartSimulationSensorNetwork();
+
+ bool resultCurrentlyRunning = (bool)PrivSim.GetFieldOrProperty("CurrentlyRunning");
+ Thread resultMonitoringThread = (Thread)PrivSim.GetFieldOrProperty("SimulationSensorMonitoringThread");
+
+ Assert.IsTrue(resultCurrentlyRunning);
+ Assert.IsTrue(resultMonitoringThread.IsAlive);
+
+ SimSensorNetwork.EndSimulationSensorNetwork();
+ }
+
+ [TestMethod]
+ public void TestEndSimulationSensorNetwork_Ends_AllObjectsBroughtDown()
+ {
+ SensorNetworkServer.StartSensorMonitoringRoutine();
+ SimSensorNetwork.StartSimulationSensorNetwork();
+
+ // Give plenty of time for everything to connect
+ Thread.Sleep(2000);
+
+ SimSensorNetwork.EndSimulationSensorNetwork();
+ SensorNetworkServer.EndSensorMonitoringRoutine();
+
+ bool resultCurrentlyRunning = (bool)PrivSim.GetFieldOrProperty("CurrentlyRunning");
+ Thread resultMonitoringThread = (Thread)PrivSim.GetFieldOrProperty("SimulationSensorMonitoringThread");
+ TcpClient resultClient = (TcpClient)PrivSim.GetFieldOrProperty("Client");
+ NetworkStream resultClientStream = (NetworkStream)PrivSim.GetFieldOrProperty("ClientStream");
+ TcpListener resultServer = (TcpListener)PrivSim.GetFieldOrProperty("Server");
+ NetworkStream resultServerStream = (NetworkStream)PrivSim.GetFieldOrProperty("ServerStream");
+
+ Assert.IsFalse(resultCurrentlyRunning);
+ Assert.IsFalse(resultMonitoringThread.IsAlive);
+ Assert.IsFalse(resultClient.Connected);
+ Assert.IsFalse(resultClientStream.CanWrite);
+ Assert.IsFalse(resultServer.Server.IsBound);
+ Assert.IsFalse(resultServerStream.CanRead);
+ }
+
+ [TestMethod]
+ public void TestBuildSubArrays_AzimuthTemp_AzimuthTempIterates()
+ {
+ // "Initialize" sensor
+ PrivSim.SetFieldOrProperty("AzimuthTempData", new double[0]);
+
+ // Populate initialized sensor
+ PrivSim.Invoke("ReadFakeDataFromCSV");
+
+ // Retrieve populated sensor
+ double[] initArray = (double[])PrivSim.GetFieldOrProperty("AzimuthTempData");
+ double[] expectedArray = new double[initArray.Length + 1]; // + 1 is to test looping back to the beginning
+ initArray.CopyTo(expectedArray, 0);
+ expectedArray[expectedArray.Length - 1] = initArray[0];
+
+ double[] resultArray = new double[expectedArray.Length];
+
+ int? index = 0;
+ int? nullInt = null;
+ SimulationSubArrayData subArrays;
+
+ for (int i = 0; i < expectedArray.Length; i++) {
+ subArrays = SimSensorNetwork.BuildSubArrays(
+ ref nullInt,
+ ref index,
+ ref nullInt,
+ ref nullInt,
+ ref nullInt,
+ ref nullInt,
+ ref nullInt
+ );
+
+ resultArray[i] = subArrays.AzimuthTemps[subArrays.AzimuthTemps.Length - 1];
+ }
+
+ Assert.IsTrue(expectedArray.SequenceEqual(resultArray));
+ }
+
+ [TestMethod]
+ public void TestBuildSubArrays_ElevationTemp_ElevationTempIterates()
+ {
+ // "Initialize" sensor
+ PrivSim.SetFieldOrProperty("ElevationTempData", new double[0]);
+
+ // Populate initialized sensor
+ PrivSim.Invoke("ReadFakeDataFromCSV");
+
+ // Retrieve populated sensor
+ double[] initArray = (double[])PrivSim.GetFieldOrProperty("ElevationTempData");
+ double[] expectedArray = new double[initArray.Length + 1]; // + 1 is to test looping back to the beginning
+ initArray.CopyTo(expectedArray, 0);
+ expectedArray[expectedArray.Length - 1] = initArray[0];
+
+ double[] resultArray = new double[expectedArray.Length];
+
+ int? index = 0;
+ int? nullInt = null;
+ SimulationSubArrayData subArrays;
+
+ for (int i = 0; i < expectedArray.Length; i++)
+ {
+ subArrays = SimSensorNetwork.BuildSubArrays(
+ ref index,
+ ref nullInt,
+ ref nullInt,
+ ref nullInt,
+ ref nullInt,
+ ref nullInt,
+ ref nullInt
+ );
+
+ resultArray[i] = subArrays.ElevationTemps[subArrays.ElevationTemps.Length - 1];
+ }
+
+ Assert.IsTrue(expectedArray.SequenceEqual(resultArray));
+ }
+
+ [TestMethod]
+ public void TestBuildSubArrays_ElevationEncoder_ElevationEncoderIterates()
+ {
+ // "Initialize" sensor
+ PrivSim.SetFieldOrProperty("ElevationEncoderData", new double[0]);
+
+ // Populate initialized sensor
+ PrivSim.Invoke("ReadFakeDataFromCSV");
+
+ // Retrieve populated sensor
+ double[] initArray = (double[])PrivSim.GetFieldOrProperty("ElevationEncoderData");
+ double[] expectedArray = new double[initArray.Length + 1]; // + 1 is to test looping back to the beginning
+ initArray.CopyTo(expectedArray, 0);
+ expectedArray[expectedArray.Length - 1] = initArray[0];
+
+ double[] resultArray = new double[expectedArray.Length];
+
+ int? index = 0;
+ int? nullInt = null;
+ SimulationSubArrayData subArrays;
+
+ for (int i = 0; i < expectedArray.Length; i++)
+ {
+ subArrays = SimSensorNetwork.BuildSubArrays(
+ ref nullInt,
+ ref nullInt,
+ ref index,
+ ref nullInt,
+ ref nullInt,
+ ref nullInt,
+ ref nullInt
+ );
+
+ resultArray[i] = subArrays.ElevationEnc[subArrays.ElevationEnc.Length - 1];
+ }
+
+ Assert.IsTrue(expectedArray.SequenceEqual(resultArray));
+ }
+
+ [TestMethod]
+ public void TestBuildSubArrays_AzimuthEncoder_AzimuthEncoderIterates()
+ {
+ // "Initialize" sensor
+ PrivSim.SetFieldOrProperty("AzimuthEncoderData", new double[0]);
+
+ // Populate initialized sensor
+ PrivSim.Invoke("ReadFakeDataFromCSV");
+
+ // Retrieve populated sensor
+ double[] initArray = (double[])PrivSim.GetFieldOrProperty("AzimuthEncoderData");
+ double[] expectedArray = new double[initArray.Length + 1]; // + 1 is to test looping back to the beginning
+ initArray.CopyTo(expectedArray, 0);
+ expectedArray[expectedArray.Length - 1] = initArray[0];
+
+ double[] resultArray = new double[expectedArray.Length];
+
+ int? index = 0;
+ int? nullInt = null;
+ SimulationSubArrayData subArrays;
+
+ for (int i = 0; i < expectedArray.Length; i++)
+ {
+ subArrays = SimSensorNetwork.BuildSubArrays(
+ ref nullInt,
+ ref nullInt,
+ ref nullInt,
+ ref index,
+ ref nullInt,
+ ref nullInt,
+ ref nullInt
+ );
+
+ resultArray[i] = subArrays.AzimuthEnc[subArrays.AzimuthEnc.Length - 1];
+ }
+
+ Assert.IsTrue(expectedArray.SequenceEqual(resultArray));
+ }
+
+ [TestMethod]
+ public void TestBuildSubArrays_ElevationAccelerometer_ElevationAccelerometerIterates()
+ {
+ // "Initialize" sensor
+ PrivSim.SetFieldOrProperty("ElevationAccData", new RawAccelerometerData[0]);
+
+ // Populate initialized sensor
+ PrivSim.Invoke("ReadFakeDataFromCSV");
+
+ // Retrieve populated sensor
+ RawAccelerometerData[] initArray = (RawAccelerometerData[])PrivSim.GetFieldOrProperty("ElevationAccData");
+ RawAccelerometerData[] expectedArray = new RawAccelerometerData[initArray.Length + 200]; // + 200 is to test looping back to the beginning
+
+ // Copy original array to expected array
+ initArray.CopyTo(expectedArray, 0);
+
+ // Get first half of the initial array for looping back
+ Array.Copy(initArray, 0, expectedArray, 400, 200);
+
+ RawAccelerometerData[] resultArray = new RawAccelerometerData[expectedArray.Length];
+
+ int? index = 0;
+ int? nullInt = null;
+ SimulationSubArrayData subArrays;
+
+ for (int i = 0; i < expectedArray.Length; i += 100)
+ {
+ subArrays = SimSensorNetwork.BuildSubArrays(
+ ref nullInt,
+ ref nullInt,
+ ref nullInt,
+ ref nullInt,
+ ref index,
+ ref nullInt,
+ ref nullInt
+ );
+
+ subArrays.ElevationAccl.CopyTo(resultArray, i);
+ }
+
+ Assert.IsTrue(expectedArray.SequenceEqual(resultArray));
+ }
+
+ [TestMethod]
+ public void TestBuildSubArrays_AzimuthAccelerometer_AzimuthAccelerometerIterates()
+ {
+ // "Initialize" sensor
+ PrivSim.SetFieldOrProperty("AzimuthAccData", new RawAccelerometerData[0]);
+
+ // Populate initialized sensor
+ PrivSim.Invoke("ReadFakeDataFromCSV");
+
+ // Retrieve populated sensor
+ RawAccelerometerData[] initArray = (RawAccelerometerData[])PrivSim.GetFieldOrProperty("AzimuthAccData");
+ RawAccelerometerData[] expectedArray = new RawAccelerometerData[initArray.Length + 200]; // + 200 is to test looping back to the beginning
+
+ // Copy original array to expected array
+ initArray.CopyTo(expectedArray, 0);
+
+ // Get first half of the initial array for looping back
+ Array.Copy(initArray, 0, expectedArray, 400, 200);
+
+ RawAccelerometerData[] resultArray = new RawAccelerometerData[expectedArray.Length];
+
+ int? index = 0;
+ int? nullInt = null;
+ SimulationSubArrayData subArrays;
+
+ for (int i = 0; i < expectedArray.Length; i += 100)
+ {
+ subArrays = SimSensorNetwork.BuildSubArrays(
+ ref nullInt,
+ ref nullInt,
+ ref nullInt,
+ ref nullInt,
+ ref nullInt,
+ ref index,
+ ref nullInt
+ );
+
+ subArrays.AzimuthAccl.CopyTo(resultArray, i);
+ }
+
+ Assert.IsTrue(expectedArray.SequenceEqual(resultArray));
+ }
+
+ [TestMethod]
+ public void TestBuildSubArrays_CounterbalanceAccelerometer_CounterbalanceAccelerometerIterates()
+ {
+ // "Initialize" sensor
+ PrivSim.SetFieldOrProperty("CounterbalanceAccData", new RawAccelerometerData[0]);
+
+ // Populate initialized sensor
+ PrivSim.Invoke("ReadFakeDataFromCSV");
+
+ // Retrieve populated sensor
+ RawAccelerometerData[] initArray = (RawAccelerometerData[])PrivSim.GetFieldOrProperty("CounterbalanceAccData");
+ RawAccelerometerData[] expectedArray = new RawAccelerometerData[initArray.Length + 200]; // + 200 is to test looping back to the beginning
+
+ // Copy original array to expected array
+ initArray.CopyTo(expectedArray, 0);
+
+ // Get first half of the initial array for looping back
+ Array.Copy(initArray, 0, expectedArray, 400, 200);
+
+ RawAccelerometerData[] resultArray = new RawAccelerometerData[expectedArray.Length];
+
+ int? index = 0;
+ int? nullInt = null;
+ SimulationSubArrayData subArrays;
+
+ for (int i = 0; i < expectedArray.Length; i += 100)
+ {
+ subArrays = SimSensorNetwork.BuildSubArrays(
+ ref nullInt,
+ ref nullInt,
+ ref nullInt,
+ ref nullInt,
+ ref nullInt,
+ ref nullInt,
+ ref index
+ );
+
+ subArrays.CounterBAccl.CopyTo(resultArray, i);
+ }
+
+ Assert.IsTrue(expectedArray.SequenceEqual(resultArray));
+ }
+
+ [TestMethod]
+ public void TestSimulationSensorMonitor_SimulationIsRunning_ConnectsToServerAndSendsData()
+ {
+ SensorNetworkServer.StartSensorMonitoringRoutine();
+ SimSensorNetwork.StartSimulationSensorNetwork();
+
+ // Give plenty of time for everything to connect
+ Thread.Sleep(2000);
+
+ Assert.AreEqual(SensorNetworkStatusEnum.ReceivingData, SensorNetworkServer.Status);
+
+ SimSensorNetwork.EndSimulationSensorNetwork();
+ SensorNetworkServer.EndSensorMonitoringRoutine();
+ }
+
+ [TestMethod]
+ public void TestSimulationSensorMonitor_ServerTriggersReboot_SimulationRebootsAndStartsSendingData()
+ {
+ SensorNetworkServer.StartSensorMonitoringRoutine();
+ SimSensorNetwork.StartSimulationSensorNetwork();
+
+ // Give plenty of time for everything to connect
+ Thread.Sleep(2000);
+
+ SensorNetworkServer.RebootSensorNetwork();
+
+ // Give plenty of time for timeout and for initialization
+ Thread.Sleep(2000 + SensorNetworkConstants.WatchDogTimeout);
+
+ Assert.AreEqual(SensorNetworkStatusEnum.ReceivingData, SensorNetworkServer.Status);
+
+ SimSensorNetwork.EndSimulationSensorNetwork();
+ SensorNetworkServer.EndSensorMonitoringRoutine();
+ }
+ }
+}
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/Simulation/TestCSVData/TestAzAccX.csv b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/Simulation/TestCSVData/TestAzAccX.csv
new file mode 100644
index 00000000..c2c5afce
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/Simulation/TestCSVData/TestAzAccX.csv
@@ -0,0 +1 @@
+6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,8
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/Simulation/TestCSVData/TestAzAccY.csv b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/Simulation/TestCSVData/TestAzAccY.csv
new file mode 100644
index 00000000..098f7b09
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/Simulation/TestCSVData/TestAzAccY.csv
@@ -0,0 +1 @@
+13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,8,8
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/Simulation/TestCSVData/TestAzAccZ.csv b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/Simulation/TestCSVData/TestAzAccZ.csv
new file mode 100644
index 00000000..7ef1d327
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/Simulation/TestCSVData/TestAzAccZ.csv
@@ -0,0 +1 @@
+11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/Simulation/TestCSVData/TestAzEnc.csv b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/Simulation/TestCSVData/TestAzEnc.csv
new file mode 100644
index 00000000..a9d9a7c0
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/Simulation/TestCSVData/TestAzEnc.csv
@@ -0,0 +1 @@
+4,5
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/Simulation/TestCSVData/TestAzTemp.csv b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/Simulation/TestCSVData/TestAzTemp.csv
new file mode 100644
index 00000000..46ebd075
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/Simulation/TestCSVData/TestAzTemp.csv
@@ -0,0 +1 @@
+2,3
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/Simulation/TestCSVData/TestCbAccX.csv b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/Simulation/TestCSVData/TestCbAccX.csv
new file mode 100644
index 00000000..c2c5afce
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/Simulation/TestCSVData/TestCbAccX.csv
@@ -0,0 +1 @@
+6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,8
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/Simulation/TestCSVData/TestCbAccY.csv b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/Simulation/TestCSVData/TestCbAccY.csv
new file mode 100644
index 00000000..098f7b09
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/Simulation/TestCSVData/TestCbAccY.csv
@@ -0,0 +1 @@
+13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,8,8
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/Simulation/TestCSVData/TestCbAccZ.csv b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/Simulation/TestCSVData/TestCbAccZ.csv
new file mode 100644
index 00000000..7ef1d327
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/Simulation/TestCSVData/TestCbAccZ.csv
@@ -0,0 +1 @@
+11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/Simulation/TestCSVData/TestElAccX.csv b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/Simulation/TestCSVData/TestElAccX.csv
new file mode 100644
index 00000000..c2c5afce
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/Simulation/TestCSVData/TestElAccX.csv
@@ -0,0 +1 @@
+6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,8
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/Simulation/TestCSVData/TestElAccY.csv b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/Simulation/TestCSVData/TestElAccY.csv
new file mode 100644
index 00000000..098f7b09
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/Simulation/TestCSVData/TestElAccY.csv
@@ -0,0 +1 @@
+13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,8,8
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/Simulation/TestCSVData/TestElAccZ.csv b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/Simulation/TestCSVData/TestElAccZ.csv
new file mode 100644
index 00000000..7ef1d327
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/Simulation/TestCSVData/TestElAccZ.csv
@@ -0,0 +1 @@
+11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/Simulation/TestCSVData/TestElEnc.csv b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/Simulation/TestCSVData/TestElEnc.csv
new file mode 100644
index 00000000..19204da5
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/Simulation/TestCSVData/TestElEnc.csv
@@ -0,0 +1 @@
+3,4
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/Simulation/TestCSVData/TestElTemp.csv b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/Simulation/TestCSVData/TestElTemp.csv
new file mode 100644
index 00000000..0e88c499
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplicationTest/EntityControllersTests/SensorNetworkTests/Simulation/TestCSVData/TestElTemp.csv
@@ -0,0 +1 @@
+1,2
\ No newline at end of file
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/Util Tests/UtilitiesTests.cs b/ControlRoomApplication/ControlRoomApplicationTest/Util Tests/UtilitiesTests.cs
new file mode 100644
index 00000000..747bc2fe
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplicationTest/Util Tests/UtilitiesTests.cs
@@ -0,0 +1,40 @@
+using System;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using ControlRoomApplication.Util;
+
+namespace ControlRoomApplication.UtilitiesTests
+{
+
+ [TestClass]
+ public class UtilitiesTests {
+
+
+ [TestMethod]
+ public void TestGetTimeStamp()
+ {
+ string timeStamp = Utilities.GetTimeStamp();
+ bool timeZone = false;
+
+ // Allow for timestamps containing both EST or EDT, rather than just EST
+ if(timeStamp.Contains("EST") || timeStamp.Contains("EDT"))
+ {
+ timeZone = true;
+ }
+
+ Assert.IsTrue(timeZone);
+
+ }
+
+ [TestMethod]
+ public void TestCheckEncrypted_NotEncrypted()
+ {
+ string receivedCommand = "1.0|efjoaifjwaovn894q9q2j8qv48qv4g4q3gq38hg93";
+
+ Tuple dataPair = Utilities.CheckEncrypted(receivedCommand);
+
+ Assert.IsTrue(receivedCommand.Equals(dataPair.Item1));
+ Assert.IsFalse(dataPair.Item2);
+ }
+ }
+}
+
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/Util Tests/ValidatorTests.cs b/ControlRoomApplication/ControlRoomApplicationTest/Util Tests/ValidatorTests.cs
new file mode 100644
index 00000000..c7081e72
--- /dev/null
+++ b/ControlRoomApplication/ControlRoomApplicationTest/Util Tests/ValidatorTests.cs
@@ -0,0 +1,237 @@
+using System;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using ControlRoomApplication.Validation;
+using System.Net.Sockets;
+using System.Net;
+
+namespace ControlRoomApplication.ValidationTests {
+
+ [TestClass]
+ public class ValidatorTests {
+
+
+ // ports for testing: valid, too high, too low, empty, wrong type
+ private int validPort1 = 8080;
+ private string validPort2 = "8080";
+
+ private int invalidPort1 = 70000;
+ private string invalidPort2 = "hello";
+ private int invalidPort3 = 0;
+ private int invalidPort4 = -10000;
+ private string invalidPort5 = "";
+
+ // IP address for testing: valid, empty, wrong type
+ private string validIP1 = "127.0.0.1";
+ private string validIP2 = "10.0.2.5";
+
+ private string invalidIP1 = "i am an invalid IP address";
+ private string invalidIP2 = "";
+
+ // Speed values for testing
+ private double validSpeed1 = 0.5;
+ private double validSpeed2 = 1.5;
+ private string validSpeed3 = "1.5";
+ private string validSpeed4 = "0.5";
+
+ private double invalidSpeed1 = 3.0;
+ private double invalidSpeed2 = -1.5;
+ private string invalidSpeed3 = "";
+ private string invalidSpeed4 = "3.0";
+
+ // speed TEXT ONLY values for testing
+ private string validTextSpeed1 = "2.0";
+ private string validTextSpeed2 = "20.0";
+ private string invalidTextSpeed1 = "hello";
+ private string invalidTextSpeed2 = "saSDASDS";
+
+ // IFGain values for testing
+ private double validIFGain1 = 10.50;
+ private double validIFGain2 = 20.50;
+ private string validIFGain3 = "10.50";
+ private string validIFGain4 = "20.50";
+
+ private double invalidIFGain1 = 50.5;
+ private double invalidIFGain2 = 5.00;
+ private string invalidIFGain3 = "50.00";
+ private string invalidIFGain4 = "";
+
+
+ // Offset Volts values testing
+ private double validVolts1 = 1.0;
+ private double validVolts2 = 3.5;
+ private string validVolts3 = "1.0";
+ private string validVolts4 = "3.5";
+
+ private double invalidVolts1 = -1.0;
+ private double invalidVolts2 = 5.0;
+ private string invalidVolts3 = "5.0";
+ private string invalidVolts4 = "";
+
+ // Frequency hertz value testing
+ private double validFrequency1 = 0.1;
+ private double validFrequency2 = 5.0;
+ private string validFrequency3 = "0.1";
+ private string validFrequency4 = "0.5";
+
+ private double invalidFrequency1 = -1.0;
+ private double invalidFrequency2 = -4.1;
+ private string invalidFrequency3 = "-1.0";
+ private string invalidFrequency4 = "-4.1";
+
+ [TestMethod]
+ public void TestPort()
+ {
+ Assert.IsTrue(Validator.ValidatePort(validPort1));
+ Assert.IsTrue(Validator.ValidatePort(validPort2));
+ Assert.IsFalse(Validator.ValidatePort(invalidPort1));
+ Assert.IsFalse(Validator.ValidatePort(invalidPort2));
+ Assert.IsFalse(Validator.ValidatePort(invalidPort3));
+ Assert.IsFalse(Validator.ValidatePort(invalidPort4));
+ Assert.IsFalse(Validator.ValidatePort(invalidPort5));
+
+ }
+
+ [TestMethod]
+ public void TestIPAddress()
+ {
+ Assert.IsTrue(Validator.ValidateIPAddress(validIP1));
+ Assert.IsTrue(Validator.ValidateIPAddress(validIP2));
+ Assert.IsFalse(Validator.ValidateIPAddress(invalidIP1));
+ Assert.IsFalse(Validator.ValidateIPAddress(invalidIP2));
+ }
+
+ [TestMethod]
+ public void TestSpeed()
+ {
+ Assert.IsTrue(Validator.ValidateSpeed(validSpeed1));
+ Assert.IsTrue(Validator.ValidateSpeed(validSpeed2));
+ Assert.IsTrue(Validator.ValidateSpeed(validSpeed3));
+ Assert.IsTrue(Validator.ValidateSpeed(validSpeed4));
+ Assert.IsFalse(Validator.ValidateSpeed(invalidSpeed1));
+ Assert.IsFalse(Validator.ValidateSpeed(invalidSpeed2));
+ Assert.IsFalse(Validator.ValidateSpeed(invalidSpeed3));
+ Assert.IsFalse(Validator.ValidateSpeed(invalidSpeed4));
+ }
+
+ [TestMethod]
+ public void TestSpeedTextOnly()
+ {
+ Assert.IsTrue(Validator.ValidateSpeedTextOnly(validTextSpeed1));
+ Assert.IsTrue(Validator.ValidateSpeedTextOnly(validTextSpeed2));
+ Assert.IsFalse(Validator.ValidateSpeedTextOnly(invalidTextSpeed1));
+ Assert.IsFalse(Validator.ValidateSpeedTextOnly(invalidTextSpeed1));
+
+
+ }
+
+ [TestMethod]
+ public void TestIFGain()
+ {
+ Assert.IsTrue(Validator.ValidateIFGain(validIFGain1));
+ Assert.IsTrue(Validator.ValidateIFGain(validIFGain2));
+ Assert.IsTrue(Validator.ValidateIFGain(validIFGain3));
+ Assert.IsTrue(Validator.ValidateIFGain(validIFGain4));
+ Assert.IsFalse(Validator.ValidateIFGain(invalidIFGain1));
+ Assert.IsFalse(Validator.ValidateIFGain(invalidIFGain2));
+ Assert.IsFalse(Validator.ValidateIFGain(invalidIFGain3));
+ Assert.IsFalse(Validator.ValidateIFGain(invalidIFGain4));
+
+
+ }
+
+ [TestMethod]
+ public void TestFrequency()
+ {
+ Assert.IsTrue(Validator.ValidateFrequency(validFrequency1));
+ Assert.IsTrue(Validator.ValidateFrequency(validFrequency2));
+ Assert.IsTrue(Validator.ValidateFrequency(validFrequency3));
+ Assert.IsTrue(Validator.ValidateFrequency(validFrequency4));
+ Assert.IsFalse(Validator.ValidateFrequency(invalidFrequency1));
+ Assert.IsFalse(Validator.ValidateFrequency(invalidFrequency2));
+ Assert.IsFalse(Validator.ValidateFrequency(invalidFrequency3));
+ Assert.IsFalse(Validator.ValidateFrequency(invalidFrequency4));
+ }
+
+ [TestMethod]
+ public void TestOffsetVoltage()
+ {
+ Assert.IsTrue(Validator.ValidateOffsetVoltage(validVolts1));
+ Assert.IsTrue(Validator.ValidateOffsetVoltage(validVolts2));
+ Assert.IsTrue(Validator.ValidateOffsetVoltage(validVolts3));
+ Assert.IsTrue(Validator.ValidateOffsetVoltage(validVolts4));
+ Assert.IsFalse(Validator.ValidateOffsetVoltage(invalidVolts1));
+ Assert.IsFalse(Validator.ValidateOffsetVoltage(invalidVolts2));
+ Assert.IsFalse(Validator.ValidateOffsetVoltage(invalidVolts3));
+ Assert.IsFalse(Validator.ValidateOffsetVoltage(invalidVolts4));
+
+
+
+ }
+
+ [TestMethod]
+ public void TestIsDouble_IsDouble_Success()
+ {
+ Assert.IsTrue(Validator.IsDouble("1.5"));
+ Assert.IsTrue(Validator.IsDouble("1"));
+ Assert.IsTrue(Validator.IsDouble("0.0"));
+ Assert.IsTrue(Validator.IsDouble("-1.2"));
+ }
+
+ [TestMethod]
+ public void TestIsDouble_NotDouble_Fail()
+ {
+ Assert.IsFalse(Validator.IsDouble("hello"));
+ Assert.IsFalse(Validator.IsDouble("."));
+ Assert.IsFalse(Validator.IsDouble("32..."));
+ Assert.IsFalse(Validator.IsDouble("25565;"));
+ }
+
+ [TestMethod]
+ public void TestIsBetween_IsBetween_Success()
+ {
+ int upper = 5;
+ int lower = -1;
+
+ Assert.IsTrue(Validator.IsBetween(lower, lower, upper));
+ Assert.IsTrue(Validator.IsBetween(upper, lower, upper));
+ Assert.IsTrue(Validator.IsBetween(lower - 1, null, upper));
+ Assert.IsTrue(Validator.IsBetween(upper + 1, lower, null));
+ }
+
+ [TestMethod]
+ public void TestIsBetween_IsNotBetween_Fail()
+ {
+ int upper = 5;
+ int lower = -1;
+
+ Assert.IsFalse(Validator.IsBetween(lower - 1, lower, upper));
+ Assert.IsFalse(Validator.IsBetween(upper + 1, lower, upper));
+ Assert.IsFalse(Validator.IsBetween(lower - 1, lower, null));
+ Assert.IsFalse(Validator.IsBetween(upper + 1, null, upper));
+ }
+
+ [TestMethod]
+ public void TestServerRunningOnIp_ServerIsRunning_Success()
+ {
+ string ip = "127.0.0.1";
+ int port = 3000;
+
+ TcpListener server = new TcpListener(IPAddress.Parse(ip), port);
+ server.Start();
+
+ Assert.IsTrue(Validator.ServerRunningOnIp(ip, port));
+
+ server.Stop();
+ }
+
+ [TestMethod]
+ public void TestServerRunningOnIp_ServerNotRunning_Fail()
+ {
+ string ip = "148.0.0.1";
+ int port = 3000;
+
+ Assert.IsFalse(Validator.ServerRunningOnIp(ip, port));
+ }
+ }
+}
+
diff --git a/ControlRoomApplication/ControlRoomApplicationTest/packages.config b/ControlRoomApplication/ControlRoomApplicationTest/packages.config
index 1a59559c..c01c0477 100644
--- a/ControlRoomApplication/ControlRoomApplicationTest/packages.config
+++ b/ControlRoomApplication/ControlRoomApplicationTest/packages.config
@@ -1,14 +1,19 @@
-
-
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
index 49cc1b33..1eb9fa34 100644
--- a/README.md
+++ b/README.md
@@ -4,69 +4,79 @@
________________________________________________________________________________________________________________________________________
Github Repository
- Website URL: https://github.com/jporter7/YCP-RT-ControlRoom
- Clone URL: https://github.com/jporter7/YCP-RT-ControlRoom.git
- Repository owner: Jason Porter
- Github account: jporter7
- E-mail: jporter7@ycp.edu
-
+ Website URL: https://github.com/kkennelly/YCP-RT-ControlRoom
+ Clone URL: https://github.com/kkennelly/YCP-RT-ControlRoom.git
+ Repository owner: Kate Kennelly
+ Github account: kkennelly
+ E-mail: kkennelly@ycp.edu
________________________________________________________________________________________________________________________________________
- Installations/Downloads
- First, to get set up, you must download and install the following applications. You should select the default options and features for all of the applications below.
-
- - Visual Studio Community 2017
- - MySQL Community Server
- - Arduino IDE (Optional - required for working with the scale model)
+ Set Up
+Repo Cloning:
-________________________________________________________________________________________________________________________________________
- Github Repository Setup
- The first thing to do in order to contribute code to the project is to get added as a contributor by the repository owner that is listed above. After you are added to the Github repository as a contributor you can move on to the Visual Studio Setup section of this manual.
+ The control room software code base is developed in Visual Studio 2017 and is hosted on Github at:
+ https://github.com/YCPRadioTelescope/YCP-RT-ControlRoom. You will need to have Visual Studio 2017
+ installed on your computer as well as an installation of git for repo cloning. Go to the link
+ shown above, copy the clone link, and then open a command line (I prefer to use git bash). Clone
+ the repo into the directory of your choice, and then open the repo in Visual Studio using the
+ solution file within the ControlRoomApplication folder.
- Steps:
- -Contact repository owner and get added as a contributor
+Package Settings:
-________________________________________________________________________________________________________________________________________
- Visual Studio Setup
- Once you have Visual Studio installed and you are added as a contributor to the Github repository, you must setup your Visual Studio environment by connecting the repository inside of Visual Studio. This will allow you to push, pull, merge, fetch, etc. to the remote repository. With Visual Studio opened already:
+ Now that we have the repo cloned, and the solution file is open, we must set up the package settings
+ for the project. Start by right clicking the project icon in the solution explorer for
+ ControlRoomApplication. In the right click menu, select Manage NuGet Packages. A new file will open
+ in the code window, allowing you to search for the necessary packages. For each package that you
+ install, take care to choose the correct version of the package. The packages you will install are:
+ EntityFramework v6.2.0, My.Sql.Data.EntityFrameWork v8.0.17, MySql.Data v8.0.17, AASharp v1.93.3,
+ and AWSSDK.RDS v3.3.38.2. Be sure to only install the packages specified, as certain other packages
+ will negate the effects of others and may break you project. Finally, for security reasons, you must
+ contact a system administrator for a copy of the AWSConstants file for access to the AWS Server’s data,
+ and the pushNotifications file for sending push notifications. The pushNotifications file belongs in
+ "ControlRoomApplication\ControlRoomApplication\Controllers\Communications\pushNotification.cs".
+ AWSConstants belongs in the Constants folder. You may have to manually add the package to the files
+ that use it. The LOCAL_DATABASE_STRING constant will have to be modified to include the password you
+ set for MySQL.
-Repository Setup Steps:
- - Go to “View” >> “Team Explorer” >> double click to open the Team Explorer window
- - In "Team Explorer” >> “Local Git Repositories” >> “Clone” >> Add the URL of the Github repository (or the SSH key if you are Mr. Savvy).
- - Edit the file path that your repository will be stored in if it is not correct.
- - Make sure that “Recursively Clone Submodules” is checked off
- - Enjoy your new Github Repository
-Dependency/References Setup Steps:
- - Go to “View” >> “Solution Explorer” >> double click to open the Solution Explorer window
- - In “Solution Explorer” >> right click “ControlRoomApplication” >> “Manage NuGet Packages” >> click “Browse” >> Search/Install the following:
- - EntityFramework (v 6.2.0)
- - MySql.Data.EntityFramework (v 8.0.13)
- -(DO NOT GET MySql.Data.Entity IT IS INCOMPATIBLE)
- - MySql.Data (v 8.0.13)
- - AASharp (1.93.3)
+MySQL Set Up:
-AWS Setup Steps:
- - Cry and contact someone that has already done it.
- - No, seriously, the database username/password info can’t be stored in a file online, so you will have to contact somebody that is already connected to get that information. It should be a file named “AWSConstants.cs”
+ The next step is the setup of the MySql Server. Follow the link here:
+ https://dev.mysql.com/downloads/windows/installer/8.0.html, and download the smaller msi file. Run the
+ file after it has finished downloading and follow the normal installation process choosing defaults for
+ all of the options until you reach the root password creation window. If the installer doesn’t ask you
+ for a password at any point during installation, uninstall the version you installed, and using the same
+ link, download the larger of the two files. Leave the username as root. The password you set can be
+ whatever you want it to be, but the password in application_local.properties in the back end and
+ LOCAL_DATABASE_STRING in the control room must match it. This will allow the Control Room to link to
+ your local MySql database. Follow through the rest of the installation process choosing defaults for
+ all of the rest of the options until the service is finished. The service should start running
+ immediately (you can look in the Services section of the Task Manager to check if it is running).
+ Finally, reopen the Control Room Application within Visual Studio, and build it. If you are still running
+ into a MySql connection error, run the MySql installer again. Select add, and then choose MySQL Connectors,
+ then Connector/NET, and then choose the version using the green arrow. Select next and follow the standard
+ installation procedure. Finally, you must install and run the RT-Contracts Application.
+
+Running the Control Room Software for the first time:
-________________________________________________________________________________________________________________________________________
- MySQL Server Setup
- MySQL server is the server provider that we are using to connect to our MySQL database that is hosted on Amazon Web Services (AWS). The only setup required for the MySQL server is that you have a local instance running on your machine. The local instance should automatically spin up after completion of the installation above. If it is not running, however, you can do the following:
+ Prior to running the Control Room Software, you will need to set up the backend portion of the project, RT-Contracts.
+ That respository along with instructions can be found here: https://github.com/YCPRadioTelescope/RT-Contracts.
+ Upon completing the setup for the backend, which will only **create** your local database(e.g. without any data),
+ you can run the Control Room software to begin populating it. If you have never run the control room before, you will
+ get a popup window stating that the "new telescope flag was set to true". Click "YES" or "OK" to allow this new telescope
+ creation to take place. This will populate your database with a new RadioTelescope instance that you can run now by placing
+ the ID of 1 inside the JSON file on subsequent runs. **NOTE:** anytime you wish to run a SPECIFIC telescope, set the
+ "newTelescope" flag to false in the JSON file, and place the ID of the telescope you wish to run inside of the "telescopeID"
+ field. This is our JSON configuration file found in the root directory of the project that will allow you to run specific
+ instances of a radio telescope from the database by its ID. Inside of the JSON file you will see something similar to this:
-Windows Startup Steps:
- - Open “Task Manager” >> “Services” tab >> locate your service(s) that are related to MySQL (they will be named MySQL___)
- - Right click the service that is not running >> “Start”
+
+
+ From here you can specify an ID or specify the newTelescope flag to be set to true (which creates
+ a new telescope). However on your first run, since you do not have any telescopes created, you will
+ need to select "YES" or "OK" on the popup window that asks you to confirm you would like to create
+ a new telescope instance. After doing so, you will be able to use the control room normally with that
+ telescope you created.
-Linux Startup Steps:
- - Open a terminal
- - Enter “sudo mysql start” (I am not 100% sure this is correct, but it’s something like this. You’re using linux, you’ve probably got this.)
-Mac Startup Steps:
- - ??????
-________________________________________________________________________________________________________________________________________
- Arduino IDE
- The Arduino IDE does not require any additional setup other than the initial default installation. After the default installation, you should be able to simply download the Arduino driver files for the stepper motors from the shared drive under Team Jupiter’s folder. After downloading the Arduino file(s), you can open them in the Arduino IDE and edit them or load them onto an Arduino board after setting the correct COM port under the “Tools” tab in the IDE.
-Steps:
- - “Tools” >> “Port” >> select the proper COM port that your USB is connected to.