private void AutomaticSnowDumpInterval(Object source, ElapsedEventArgs e) { double DELTA = 0.01; Orientation currentOrientation = GetCurrentOrientation(); // 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"); } } } }
/// <summary> /// 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 /// </summary> /// <param name="sensor"></param> /// <param name="set"></param> 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); } 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."); } }
public void TestSendingEmailToAllAdmins() { string sender = "*****@*****.**"; 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 <bool> task = EmailNotifications.sendToAllAdmins(subject, body, sender, true); // Wait for main task to finish before assertion task.Wait(); Assert.IsTrue(task.Result); }
public void WeatherMonitoringRoutine() { while (KeepWeatherMonitoringThreadAlive) { 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(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); } }
/// <summary> /// fires whenever the data on the modbus server changes /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Server_Written_to_handler(object sender, DataStoreEventArgs e) { //e.Data.B //array representing data 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_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_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_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.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_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_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.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.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"); 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"); 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; } } }
/// <summary> /// 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 /// </summary> /// <returns>override bool</returns> public bool checkTemp(Temperature t, bool lastIsSafe) { // 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) { 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); } } 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); }
//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: double azimuthPos = 0; double elevationPos = 0; string input = ""; string[] values; Entities.Orientation currentOrientation = rtController.GetCurrentOrientation(); // Get validated user input for azimuth position do { input = Interaction.InputBox("The Radio Telescope is currently set to be type " + rtController.RadioTelescope.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 " + Constants.SimulationConstants.LIMIT_LOW_EL_DEGREES + " and " + Constants.SimulationConstants.LIMIT_HIGH_EL_DEGREES + " degrees. Format the entry as a comma-separated list in the format " + "azimuth, elevation. Ex: 55,80", "Azimuth Orientation", currentOrientation.Azimuth.ToString() + "," + currentOrientation.Elevation.ToString()); values = input.Split(','); if (values.Length == 2 && !input.Equals("")) { Double.TryParse(values[0], out azimuthPos); Double.TryParse(values[1], out elevationPos); } // check to make sure the entered values are valid, that there are not too many values entered, and that the entry was formatted correctly }while ((azimuthPos > 360 || azimuthPos < 0) || (elevationPos > Constants.SimulationConstants.LIMIT_HIGH_EL_DEGREES || elevationPos <= Constants.SimulationConstants.LIMIT_LOW_EL_DEGREES) && (!input.Equals("") && values.Length <= 2)); // Only run script if cancel button was not hit if (!input.Equals("")) { Entities.Orientation moveTo = new Entities.Orientation(azimuthPos, elevationPos); movementResult = rtController.MoveRadioTelescopeToOrientation(moveTo, MovementPriority.Manual); } else { MessageBox.Show("Custom Orientation script cancelled.", "Script Cancelled"); } 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; 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()}"); } }); }