/// <summary> /// Handle a mouse double-click event /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void pnlElements_MouseDoubleClick(object sender, MouseEventArgs e) { //Find our element foreach (MM_OneLine_Element Elem in DisplayComponents) { if (Elem.BaseElement != null && Elem.Bounds.Contains((int)((e.X / ZoomLevel) - pnlElements.AutoScrollPosition.X), (int)((e.Y / ZoomLevel) - pnlElements.AutoScrollPosition.Y))) { MM_OneLine_Element SelectedElement = null; if (Elem.ElemType == MM_OneLine_Element.enumElemTypes.Descriptor || Elem.ElemType == MM_OneLine_Element.enumElemTypes.SecondaryDescriptor) { SelectedElement = Elem.ParentElement; } else { SelectedElement = Elem; } if (SelectedElement.ElemType == MM_OneLine_Element.enumElemTypes.Line && BaseElement is MM_Substation) { MM_Line Line = (MM_Line)SelectedElement.BaseElement; if (Line.Substation1 == BaseElement) { LoadOneLine(Line.Substation2, Line); } else { LoadOneLine(Line.Substation1, Line); } } else if (SelectedElement.ElemType == MM_OneLine_Element.enumElemTypes.Node) { if (BaseElement is MM_Substation) { LoadOneLine(SelectedElement.Contingencies[0], SelectedElement.BaseElement); } else { LoadOneLine(SelectedElement.BaseElement.Substation, SelectedElement.BaseElement); } } else if (SelectedElement.BaseElement != null && SelectedElement.BaseElement.ElemType.Configuration != null && SelectedElement.BaseElement.ElemType.Configuration["ControlPanel"] != null) { if (MM_Server_Interface.ClientAreas.ContainsKey("ERCOT") || MM_Server_Interface.ClientAreas.ContainsKey(SelectedElement.BaseElement.Operator.Alias)) { new MM_ControlPanel(Elem, SelectedElement.BaseElement.ElemType.Configuration["ControlPanel"], this) { StartPosition = FormStartPosition.Manual, Location = Cursor.Position } }
/// <summary> /// Handle the user's response /// </summary> /// <param name="LngLat"></param> public void HandleResponse(PointF LngLat) { //If we're a substation, find our position relative to the sub Double Dist; UserAnswer = LngLat; if (TargetElement is MM_Substation) { Dist = (TargetElement as MM_Substation).DistanceTo(LngLat); CorrectAnswer = (TargetElement as MM_Substation).LngLat; } else { MM_Line TargetLine = (MM_Line)TargetElement; Dist = MM_Substation.ComputeDistance(LngLat, CorrectAnswer = new PointF((TargetLine.Substation1.Longitude + TargetLine.Substation2.Longitude) / 2f, (TargetLine.Substation1.Latitude + TargetLine.Substation2.Latitude) / 2f)); } //Now, check through our list of reponses, and see if we made it QuestionsAnswered++; if (Dist > CurrentLevel.NoScoreThreshold) { AnswerText = "Sorry! You were " + Dist.ToString("#,##0.0") + " miles away."; TimeQuestionPresented = DateTime.Now; TrainingMode = enumTrainingMode.AnswerWrong; QuestionsWrong++; } else { double TotalScore; if (Dist <= CurrentLevel.BullsEyeThresholdDistance) { TotalScore = CurrentLevel.UpperScoreValue; } else { double XPercentile = (Dist - CurrentLevel.BullsEyeThresholdDistance) / (CurrentLevel.NoScoreThreshold - CurrentLevel.BullsEyeThresholdDistance); TotalScore = ((CurrentLevel.LowerScoreValue - CurrentLevel.UpperScoreValue) * XPercentile) + CurrentLevel.UpperScoreValue; } double TimeScore = CurrentLevel.MaximumTimeScore * ((CurrentLevel.QuestionTimeout - TimeSincePresentation) / CurrentLevel.QuestionTimeout); Score += TimeScore + TotalScore; LevelScore += TimeScore + TotalScore; QuestionsRight += 1; AnswerText = "Correct! You were " + Dist.ToString("#,##0.0") + " miles away (" + TotalScore.ToString("0") + " pts; bonus " + TimeScore.ToString("0") + " pts)"; TimeQuestionPresented = DateTime.Now; TrainingMode = enumTrainingMode.AnswerCorrect; } }
/// <summary> /// Update the status of our element /// </summary> /// <param name="SelectedElement"></param> public void UpdateElement(MM_Element SelectedElement) { //Show our element in our selection list lblElementValue.Text = SelectedElement.ToString(); if (SelectedElement is MM_Substation) { MM_Substation BaseSubstation = SelectedElement as MM_Substation; txtSubLatitude.Visible = txtSubLongitude.Visible = true; txtSubLongitude.Text = BaseSubstation.Longitude.ToString(); txtSubLatitude.Text = BaseSubstation.Latitude.ToString(); dgvLineLngLat.Visible = false; } else { MM_Line BaseLine = SelectedElement as MM_Line; txtSubLatitude.Visible = txtSubLongitude.Visible = false; dgvLineLngLat.Visible = true; LineCoordinates.Rows.Clear(); for (int a = 0; a < BaseLine.Coordinates.Count; a++) { LineCoordinates.Rows.Add(a, BaseLine.Coordinates[a].Y, BaseLine.Coordinates[a].X); } } }
public static void CalculateCoords(LineProxy proxy, MM_Line line, int zoomLevel) { proxy.Coordinates.Clear(); //Ignore invalid lines if (float.IsNaN(line.CenterLngLat.X)) { return; } // flip the line coords if (line.Coordinates.Count > 0 && (line.Substation2.LngLat == line.Coordinates[0] || line.Substation1.LngLat == line.Coordinates[line.Coordinates.Count - 1])) { line.Coordinates.Reverse(); } if (line.Coordinates.Count == 0) { line.Coordinates.Add(line.Substation1.LngLat); line.Coordinates.Add(line.Substation2.LngLat); } //Determine if we need to flip coordinates because the substations have changed if (line.Coordinates.Count > 0 && (line.Substation2.LngLat == line.Coordinates[0] || line.Substation1.LngLat == line.Coordinates[line.Coordinates.Count - 1])) { line.Coordinates.Reverse(); } Vector2 lastPoint = Vector2.Zero; Vector2 aggPoint = Vector2.Zero; float minX = float.MaxValue; float minY = float.MaxValue; float maxY = float.MinValue; float maxX = float.MinValue; float length = 0; if (proxy.Segments == null) { proxy.Segments = new List <LineSegment>(); } else { proxy.Segments.Clear(); } if (line.Coordinates.Count > 0) { for (int i = 0; i < line.Coordinates.Count; i++) { PointF Pt = line.Coordinates[i]; Vector2 currentPoint = MM_Coordinates.LngLatToScreenVector2(Pt, zoomLevel); if (lastPoint.IsZero || lastPoint.X != currentPoint.X || lastPoint.Y != currentPoint.Y) { aggPoint.X += currentPoint.X; aggPoint.Y += currentPoint.Y; } proxy.Coordinates.Add(currentPoint); if (currentPoint.X < minX) { minX = currentPoint.X; } if (currentPoint.X > maxX) { maxX = currentPoint.X; } if (currentPoint.Y < minY) { minY = currentPoint.Y; } if (currentPoint.Y > maxY) { maxY = currentPoint.Y; } if (i > 0) { var segment = new LineSegment(lastPoint, currentPoint); proxy.Segments.Add(segment); length += segment.length; } lastPoint = currentPoint; } } proxy.Length = length; var bounds = new SharpDX.RectangleF(minX, minY, maxX - minX, maxY - minY); proxy.Bounds = bounds; lastPoint = proxy.Coordinates[proxy.Coordinates.Count - 1]; proxy.Center = new Vector2(aggPoint.X / (float)proxy.Coordinates.Count, aggPoint.Y / (float)proxy.Coordinates.Count); var lineAngle = (float)Math.Atan2(proxy.Coordinates[0].Y - lastPoint.Y, proxy.Coordinates[0].X - lastPoint.X); // if (lineAngle < 0) // { // lineAngle += (float)(Math.PI * 2); // } if (lineAngle > (float)Math.PI / 2f) { lineAngle = (float)lineAngle - (float)Math.PI; proxy.FlipSides = true; } else if (lineAngle < (float)Math.PI / -2f) { lineAngle = (float)lineAngle - (float)Math.PI; proxy.FlipSides = true; } else { proxy.FlipSides = false; } //lineAngle *= 180f / (float)Math.PI; proxy.Angle = lineAngle; }
public void CalculateCoords(MM_Line line, int zoomLevel) { LineProxy.CalculateCoords(this, line, zoomLevel); }
/// <summary> /// When the primary/secondary path is selected, display all of our elements /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void cmbPrimarySecondary_SelectedIndexChanged(object sender, EventArgs e) { try { lvItems.Columns.Clear(); lvItems.Items.Clear(); lvItems.View = View.Details; lvItems.Columns.Add("#"); lvItems.Columns.Add("Action"); lvItems.Columns.Add("Subsatation"); lvItems.Columns.Add("Type"); lvItems.Columns.Add("Element"); lvItems.Columns.Add("Operator"); lvItems.FullRowSelect = true; lvItems.CheckBoxes = true; MM_Blackstart_Corridor_Target Target = cmbCorridorTarget.SelectedItem as MM_Blackstart_Corridor_Target; FieldInfo fI = Target.GetType().GetField(cmbPrimarySecondary.Text); if (Target != null && fI != null) { MM_Blackstart_Corridor_Element[] Elems = fI.GetValue(Target) as MM_Blackstart_Corridor_Element[]; MM_Substation LastSub = null; for (int a = 0; a < Elems.Length; a++) { try { ListViewItem lvI = new ListViewItem((a + 1).ToString("#,##0")); lvI.UseItemStyleForSubItems = true; if (MM_Server_Interface.Client != null && Array.IndexOf(Data_Integration.UserOperatorships, 999999) == -1 && Array.IndexOf(Data_Integration.UserOperatorships, Elems[a].AssociatedElement.Operator.TEID) == -1) { lvI.ForeColor = Color.Gray; } lvI.SubItems.Add(Elems[a].Action.ToString()); if (Elems[a].AssociatedElement != null) { MM_Element Elem = Elems[a].AssociatedElement; if (Elem is MM_Line) { MM_Line Line = (MM_Line)Elem; if (LastSub == Line.Substation2) { lvI.SubItems.Add(Line.Substation2.Name + " to " + Line.Substation1.Name); } else { lvI.SubItems.Add(Line.Substation1.Name + " to " + Line.Substation2.Name); } LastSub = Line.Substation2; } else { lvI.SubItems.Add(Elem.Substation.Name); LastSub = Elem.Substation; } lvI.SubItems.Add(Elem.ElemType.Name); lvI.SubItems.Add(MM_Repository.TitleCase(Elem.Name)); lvI.SubItems.Add(Elem.Operator.Alias.Substring(0, 1) + MM_Repository.TitleCase(Elem.Operator.Alias.Substring(1))); } else { if (Elems[a].Substation == null) { lvI.SubItems.Add("?"); } else { lvI.SubItems.Add(MM_Repository.TitleCase(Elems[a].Substation.Name)); } lvI.SubItems.Add("?"); lvI.SubItems.Add("?"); lvI.SubItems.Add("?"); lvI.ForeColor = Color.Red; lvI.UseItemStyleForSubItems = true; } lvI.Tag = Elems[a]; lvItems.Items.Add(lvI); } catch (Exception ex) { MM_System_Interfaces.LogError(ex); } } tmrUpdate_Tick(tmrUpdate, EventArgs.Empty); lvItems.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent); } } catch (Exception) { } }
/// <summary> /// Ask our next question /// </summary> private void AskNextQuestion() { try { //Come up with a question int QuestionType = rnd.Next(1, 13); //1. Which of the following substations has a wind farm //2. Which of the following substations has a unit operated by X //3. Which of the following lines is highly congested? //4. Which of the following stations is in county X? //5. Which of the following lines is 345 KV? //6. Which of the following lines goes between county X and Y //7. Which county has the lowest bus voltages //8. Which county has the highest available reactive voltage support potential? //9: Which county has the highest available reactive capacitive support potential? //10: Which substation is operated by the following TO: //11: Which line is operated by the following TO: //12: Which Unit is operated by the following QSE? String Question = null; MM_Element[] Elems = new MM_Element[4]; if (QuestionType == 1) { Question = "Which station has a wind gen?"; List <MM_Substation> Subs = new List <MM_Substation>(MM_Repository.Substations.Values); for (int a = 0; a < 4; a++) { while (Elems[a] == null) { MM_Substation Sub = Subs[rnd.Next(Subs.Count)]; if (a == 0 && Sub.Units != null && Sub.Units.Count > 0 && Sub.Units[0].UnitType.Name == "Wind" && Sub.LongName.IndexOf("Wind", StringComparison.CurrentCultureIgnoreCase) == -1) { Elems[a] = Sub; } else if (a != 0 && Sub.Units != null && Sub.Units.Count > 0 && Sub.Units[0].UnitType.Name != "Wind") { Elems[a] = Sub; } } } } else if (QuestionType == 10 || QuestionType == 11) { for (int a = 0; a < 4; a++) { while (Elems[a] == null) { if (QuestionType == 10) { List <MM_Substation> Subs = new List <MM_Substation>(MM_Repository.Substations.Values); MM_Substation Sub = Subs[rnd.Next(Subs.Count)]; if (a == 0) { Elems[0] = Sub; } else if (!Sub.Operator.Equals(Elems[0].Operator)) { Elems[a] = Sub; } Question = "Which station is operated by " + Elems[0].Operator.Name + "?"; } else if (QuestionType == 11) { List <MM_Line> Lines = new List <MM_Line>(MM_Repository.Lines.Values); MM_Line Line = Lines[rnd.Next(Lines.Count)]; if (a == 0) { Elems[0] = Line; } else if (!Line.Operator.Equals(Elems[0].Operator)) { Elems[a] = Line; } Question = "Which line is operated by " + Elems[0].Operator.Name + "?"; } } } } else if (QuestionType == 2 || QuestionType == 12) { List <MM_Substation> Subs = new List <MM_Substation>(MM_Repository.Substations.Values); MM_Company FoundQSE = null; for (int a = 0; a < 4; a++) { while (Elems[a] == null) { MM_Substation Sub = Subs[rnd.Next(Subs.Count)]; if (a == 0 && Sub.Units != null && Sub.Units.Count > 0) { if (QuestionType == 2) { Elems[a] = Sub; } else { Elems[a] = Sub.Units[0]; } FoundQSE = Sub.Units[0].Operator; } else if (a != 0 && Sub.Units != null && Sub.Units.Count > 0 && Sub.LongName.IndexOf(FoundQSE.Name, StringComparison.CurrentCultureIgnoreCase) == -1) { bool FoundOne = false; foreach (MM_Unit Unit in Sub.Units) { if (Unit.Operator.Equals(FoundQSE)) { FoundOne = true; } } if (!FoundOne) { if (QuestionType == 2) { Elems[a] = Sub; } else { Elems[a] = Sub.Units[0]; } } } } } if (QuestionType == 2) { Question = "Which substation has unit(s) operated by " + FoundQSE.Name + "?"; } else { Question = "Which unit is operated by " + FoundQSE.Name + "?"; } } else if (QuestionType == 3) { List <MM_Line> Lines = new List <MM_Line>(MM_Repository.Lines.Values); MM_Line CongestedLine = null; while (CongestedLine == null) { MM_Line TestLine = Lines[rnd.Next(Lines.Count)]; if (TestLine.LineEnergizationState.Name.EndsWith("Energized") && !TestLine.IsSeriesCompensator && TestLine.LinePercentage >= .7f) { CongestedLine = TestLine; } } Elems[0] = CongestedLine; Question = "Which line is highly congested (" + CongestedLine.LinePercentageText + ")?"; for (int a = 1; a < 4; a++) { while (Elems[a] == null) { MM_Line TestLine = Lines[rnd.Next(Lines.Count)]; if (TestLine.LineEnergizationState.Name.EndsWith("Energized") && !TestLine.IsSeriesCompensator && TestLine.LinePercentage <= .4f) { Elems[a] = TestLine; } } } } else if (QuestionType == 4) { List <MM_Boundary> Bounds = new List <MM_Boundary>(MM_Repository.Counties.Values); List <MM_Substation> Subs = new List <MM_Substation>(MM_Repository.Substations.Values); MM_Boundary FoundBound = null; while (FoundBound == null || FoundBound.Substations.Count == 0) { FoundBound = Bounds[rnd.Next(Bounds.Count)]; } Question = "Which substation is in " + FoundBound.Name + " county?"; Elems[0] = FoundBound.Substations[rnd.Next(FoundBound.Substations.Count)]; for (int a = 1; a < 4; a++) { while (Elems[a] == null) { MM_Substation Sub = Subs[rnd.Next(Subs.Count)]; if (!Sub.County.Equals(FoundBound)) { Elems[a] = Sub; } } } } else if (QuestionType == 5) { MM_KVLevel VoltageToFind = new MM_KVLevel[] { MM_Repository.KVLevels["345 KV"], MM_Repository.KVLevels["138 KV"], MM_Repository.KVLevels["69 KV"] }[rnd.Next(3)]; List <MM_Line> Lines = new List <MM_Line>(MM_Repository.Lines.Values); for (int a = 0; a < 4; a++) { while (Elems[a] == null) { MM_Line TestLine = Lines[rnd.Next(Lines.Count)]; if (!TestLine.IsSeriesCompensator) { if (a == 0 && TestLine.KVLevel.Equals(VoltageToFind)) { Elems[a] = TestLine; } else if (a != 0 && !TestLine.KVLevel.Equals(VoltageToFind)) { Elems[a] = TestLine; } } } } Question = "Which line is " + VoltageToFind.Name + "?"; } else if (QuestionType == 6) { List <MM_Line> Lines = new List <MM_Line>(MM_Repository.Lines.Values); MM_Boundary Bound1 = null, Bound2 = null; for (int a = 0; a < 4; a++) { while (Elems[a] == null) { MM_Line TestLine = Lines[rnd.Next(Lines.Count)]; if (TestLine.IsSeriesCompensator) { } else if (a == 0 && !TestLine.Substation1.County.Equals(TestLine.Substation2.County)) { Elems[a] = TestLine; Bound1 = TestLine.Substation1.County; Bound2 = TestLine.Substation2.County; } else if (a != 0 && !TestLine.Substation1.County.Equals(Bound1) && !TestLine.Substation1.County.Equals(Bound2) && !TestLine.Substation2.County.Equals(Bound1) && !TestLine.Substation2.County.Equals(Bound2)) { Elems[a] = TestLine; } } } Question = "Which line travels between " + Bound1.Name + " and " + Bound2.Name + " (" + (Elems[0] as MM_Line).Length.ToString("#,##0.0") + " mi est.)?"; } else if (QuestionType == 7) { MM_Boundary LowestBound = null; float LowestpU = float.NaN; foreach (MM_Boundary Bound in MM_Repository.Counties.Values) { if (Bound.Substations.Count > 0) { float pU = Bound.Average_pU; if (float.IsNaN(LowestpU) || LowestpU > pU) { LowestBound = Bound; LowestpU = pU; } } } List <MM_Boundary> Bounds = new List <MM_Boundary>(MM_Repository.Counties.Values); Elems[0] = LowestBound; for (int a = 1; a < 4; a++) { while (Elems[a] == null) { MM_Boundary TestBound = Bounds[rnd.Next(0, Bounds.Count)]; if (TestBound.Substations.Count > 0 && TestBound.Average_pU > LowestpU + .1f) { Elems[a] = TestBound; } } } Question = "Which county has the lowest avg. bus voltage, at " + LowestpU.ToString("0.00%") + " pU?"; } else if (QuestionType == 8 || QuestionType == 9) { List <MM_Boundary> Bounds = new List <MM_Boundary>(); List <float> ReactivePotentials = new List <float>(); float MaxReac = float.NaN; foreach (MM_Boundary Bound in MM_Repository.Counties.Values) { if (Bound.Substations.Count > 0) { float ReacAvail = 0; int NumReacs = 0; foreach (MM_Substation Sub in Bound.Substations) { if (Sub.ShuntCompensators != null) { foreach (MM_ShuntCompensator SC in Sub.ShuntCompensators) { if (SC.Open && ((QuestionType == 8 && SC.ElemType.Name == "Reactor") || (QuestionType == 9 && SC.ElemType.Name == "Capacitor"))) { NumReacs++; ReacAvail += Math.Abs(SC.Nominal_MVAR); } } } } Bounds.Add(Bound); ReactivePotentials.Add(ReacAvail); if (float.IsNaN(MaxReac) || MaxReac < ReacAvail) { Elems[0] = Bound; MaxReac = ReacAvail; } } } Question = "Which county has the largest available " + (QuestionType == 8 ? "reactive" : "capacitive") + " voltage support (" + MaxReac.ToString("#,##0.0") + " MVar)?"; for (int a = 1; a < 4; a++) { while (Elems[a] == null) { Elems[a] = Bounds[rnd.Next(0, Bounds.Count)]; } } } lblQuestion.Text = Question; int[] OutVals = new int[] { -1, -1, -1, -1 }; for (int a = 0; a < OutVals.Length; a++) { while (OutVals[a] == -1) { bool FoundIt = false; int Next = rnd.Next(0, 4); for (int b = 0; b < a; b++) { if (OutVals[b] == Next) { FoundIt = true; } } if (!FoundIt) { OutVals[a] = Next; } } } int MaxRight = Math.Max(lblQuestion.Right, lblScore.Right); for (int a = 0; a < 4; a++) { Label lbl = Controls["lblAnswer" + (a + 1).ToString()] as Label; if (Elems[OutVals[a]] is MM_Substation) { MM_Substation Sub = Elems[OutVals[a]] as MM_Substation; if (Sub.LongName == Sub.Name) { lbl.Text = (a + 1).ToString() + ") " + Sub.LongName; } else { lbl.Text = (a + 1).ToString() + ") " + Sub.LongName + " (" + Sub.Name + ")"; } } else if (Elems[OutVals[a]] is MM_Boundary) { lbl.Text = (a + 1).ToString() + ") " + Elems[OutVals[a]].Name; } else { lbl.Text = (a + 1).ToString() + ") " + Elems[OutVals[a]].ElementDescription(); } lbl.Tag = new KeyValuePair <MM_Element, bool>(Elems[OutVals[a]], OutVals[a] == 0); lbl.BackColor = lbl.Parent.BackColor; lbl.BorderStyle = BorderStyle.None; lbl.AutoSize = true; MaxRight = Math.Max(MaxRight, lbl.Right); } this.Width = MaxRight + 20; this.Refresh(); pbTimeLeft.Value = 30; tmrQuestion.Enabled = true; tmrQuestion.Interval = 1000; IsAnswered = false; } catch (Exception) { AskNextQuestion(); } }
/// <summary> /// Initialize a new display /// </summary> /// <param name="Line"></param> /// <param name="Disp"></param> public MM_Line_Display(MM_Line Line, MM_Operatorship_Display Disp) : base(Line, Disp) { this.Line = Line; }
/// <summary> /// Refresh our list of operated equipment /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnRefresh_Click(object sender, EventArgs e) { OperatedSubstations.Clear(); MM_Substation_Display FoundSub = null; Dictionary <int, MM_Line> LineCollection = new Dictionary <int, MM_Line>(); bool IsMaster = MM_Server_Interface.ClientAreas.ContainsKey("ERCOT"); foreach (MM_Element Elem in MM_Repository.TEIDs.Values) { if (Elem.ElemType != null && Elem.Operator != null && Elem is MM_Blackstart_Corridor_Element == false && (IsMaster || MM_Server_Interface.ClientAreas.ContainsKey(Elem.Operator.Alias))) { if (Elem.Substation != null) { if (!OperatedSubstations.TryGetValue(Elem.Substation.TEID, out FoundSub)) { OperatedSubstations.Add(Elem.Substation.TEID, FoundSub = new MM_Substation_Display(Elem.Substation, this)); } if (Elem.ElemType.Name == "Breaker") { FoundSub.Breakers++; } else if (Elem.ElemType.Name == "Switch") { FoundSub.Switches++; } else if (Elem.ElemType.Name == "Capacitor") { FoundSub.Capacitors++; } else if (Elem.ElemType.Name == "Reactor") { FoundSub.Reactors++; } else if (Elem.ElemType.Name == "StaticVarCompensator") { FoundSub.SVCs++; } } else if (Elem is MM_Line) { MM_Line Line = (MM_Line)Elem; if (!Line.IsSeriesCompensator) { foreach (MM_Substation Sub in Line.ConnectedStations) { if (!OperatedSubstations.TryGetValue(Sub.TEID, out FoundSub)) { OperatedSubstations.Add(Sub.TEID, FoundSub = new MM_Substation_Display(Sub, this)); } FoundSub.Lines++; if (!LineCollection.ContainsKey(Line.TEID)) { LineCollection.Add(Line.TEID, Line); } } } } } } //Clear our lines and loads tables dgvLines.Elements.Clear(); dgvUnits.Elements.Clear(); dgvSubstations.Elements.Clear(); //Now, write out each element dgvSubstations.Elements.RaiseListChangedEvents = false; dgvUnits.Elements.RaiseListChangedEvents = false; dgvLines.Elements.RaiseListChangedEvents = false; foreach (MM_Substation_Display Sub in OperatedSubstations.Values) { dgvSubstations.Elements.Add(Sub); if (Sub.Substation.Units != null) { foreach (MM_Unit Unit in Sub.Substation.Units) { if (MM_Server_Interface.ClientAreas.ContainsKey("ERCOT") || MM_Server_Interface.ClientAreas.ContainsKey(Unit.Operator.Alias)) { dgvUnits.Elements.Add(new MM_Unit_Display(Unit, this)); } } } } foreach (MM_Line Line in LineCollection.Values) { dgvLines.Elements.Add(new MM_Line_Display(Line, this)); } dgvSubstations.Elements.RaiseListChangedEvents = false; dgvUnits.Elements.RaiseListChangedEvents = false; dgvLines.Elements.RaiseListChangedEvents = false; dgvSubstations.Elements.ResetBindings(); dgvUnits.Elements.ResetBindings(); dgvLines.Elements.ResetBindings(); }
/// <summary> /// Build the list of words for this item /// </summary> /// <param name="Elem"></param> /// <param name="OutWords"></param> private void BuildWords(MM_Element Elem, Dictionary <String, bool> OutWords) { OutWords.Clear(); if (!String.IsNullOrEmpty(Elem.Name)) { AddWord(OutWords, Elem.Name); } if (Elem is MM_Substation) { MM_Substation Sub = Elem as MM_Substation; if (!String.IsNullOrEmpty(Sub.LongName)) { AddWord(OutWords, Sub.LongName); } if (Sub.County != null) { AddWord(OutWords, Sub.County.Name); } if (Sub.LoadZone != null) { AddWord(OutWords, Sub.LoadZone.Name); } if (Sub.WeatherZone != null) { AddWord(OutWords, Sub.WeatherZone.Name); } if (Sub.Units != null) { foreach (MM_Unit Unit in Sub.Units) { AddWord(OutWords, Unit.UnitType.Name); if (!String.IsNullOrEmpty(Unit.UnitType.EMSName)) { AddWord(OutWords, Unit.UnitType.EMSName); } if (Data_Integration.NetworkSource.Estimates && Data_Integration.UseEstimates) { AddWord(OutWords, Unit.Estimated_MW > 1f ? "Online" : "Offline"); } else { AddWord(OutWords, Unit.Telemetered_MW > 1f ? "Online" : "Offline"); } } } if (Sub.Loads != null) { foreach (MM_Load Load in Sub.Loads) { if (Data_Integration.NetworkSource.Estimates && Data_Integration.UseEstimates) { AddWord(OutWords, Load.Estimated_MW > 1f ? "Online" : "Offline"); } else { AddWord(OutWords, Load.Telemetered_MW > 1f ? "Online" : "Offline"); } } } } else if (Elem is MM_Unit) { MM_Unit Unit = Elem as MM_Unit; AddWord(OutWords, Unit.UnitType.Name); if (!String.IsNullOrEmpty(Unit.UnitType.EMSName)) { AddWord(OutWords, Unit.UnitType.EMSName); } if (Data_Integration.NetworkSource.Estimates && Data_Integration.UseEstimates) { AddWord(OutWords, Unit.Estimated_MW > 1f ? "Online" : "Offline"); } else { AddWord(OutWords, (!float.IsNaN(Unit.Telemetered_MW) && Unit.Telemetered_MW != 0 ? Unit.Telemetered_MW : Unit.Estimated_MW) > 1f ? "Online" : "Offline"); } } else if (Elem is MM_Load) { MM_Load Load = Elem as MM_Load; if (Data_Integration.NetworkSource.Estimates && Data_Integration.UseEstimates) { AddWord(OutWords, Load.Estimated_MW > 1f ? "Online" : "Offline"); } else { AddWord(OutWords, (!float.IsNaN(Load.Telemetered_MW) && Load.Telemetered_MW != 0 ? Load.Telemetered_MW : Load.Estimated_MW) > 1f ? "Online" : "Offline"); } } else if (Elem is MM_ShuntCompensator) { AddWord(OutWords, (Elem as MM_ShuntCompensator).Open ? "Open" : "Closed"); } if (Elem.Operator != null) { AddWord(OutWords, Elem.Operator.Name); AddWord(OutWords, Elem.Operator.Alias); } if (Elem.Owner != null) { AddWord(OutWords, Elem.Owner.Name); AddWord(OutWords, Elem.Owner.Alias); } if (Elem.Substation != null) { AddWord(OutWords, Elem.Substation.Name); AddWord(OutWords, Elem.Substation.LongName); if (Elem.Substation.County != null) { AddWord(OutWords, Elem.Substation.County.Name); } if (Elem.Substation.LoadZone != null) { AddWord(OutWords, Elem.Substation.LoadZone.Name); } if (Elem.Substation.WeatherZone != null) { AddWord(OutWords, Elem.Substation.WeatherZone.Name); } if (Elem.Substation.Units != null) { foreach (MM_Unit Unit in Elem.Substation.Units) { AddWord(OutWords, Unit.UnitType.Name); if (!string.IsNullOrEmpty(Unit.UnitType.EMSName)) { AddWord(OutWords, Unit.UnitType.EMSName); } if (Data_Integration.NetworkSource.Estimates && Data_Integration.UseEstimates) { if (Data_Integration.NetworkSource.Estimates && Data_Integration.UseEstimates) { AddWord(OutWords, Unit.Estimated_MW > 1f ? "Online" : "Offline"); } else { AddWord(OutWords, (!float.IsNaN(Unit.Telemetered_MW) && Unit.Telemetered_MW != 0 ? Unit.Telemetered_MW : Unit.Estimated_MW) > 1f ? "Online" : "Offline"); } } } } if (Elem.Substation.Loads != null) { foreach (MM_Load Load in Elem.Substation.Loads) { if (Data_Integration.NetworkSource.Estimates && Data_Integration.UseEstimates) { if (Data_Integration.NetworkSource.Estimates && Data_Integration.UseEstimates) { AddWord(OutWords, Load.Estimated_MW > 1f ? "Online" : "Offline"); } else { AddWord(OutWords, (!float.IsNaN(Load.Telemetered_MW) && Load.Telemetered_MW != 0 ? Load.Telemetered_MW : Load.Estimated_MW) > 1f ? "Online" : "Offline"); } } } } } if (Elem is MM_Line) { MM_Line Line = Elem as MM_Line; AddWord(OutWords, Line.ConnectedStations[0].Name); AddWord(OutWords, Line.ConnectedStations[0].LongName); AddWord(OutWords, Line.ConnectedStations[1].Name); AddWord(OutWords, Line.ConnectedStations[1].LongName); if (Line.ConnectedStations[0].County != null) { AddWord(OutWords, Line.ConnectedStations[0].County.Name); } if (Line.ConnectedStations[0].LoadZone != null) { AddWord(OutWords, Line.ConnectedStations[0].LoadZone.Name); } if (Line.ConnectedStations[0].WeatherZone != null) { AddWord(OutWords, Line.ConnectedStations[0].WeatherZone.Name); } if (Line.ConnectedStations[1].County != null) { AddWord(OutWords, Line.ConnectedStations[1].County.Name); } if (Line.ConnectedStations[1].LoadZone != null) { AddWord(OutWords, Line.ConnectedStations[1].LoadZone.Name); } if (Line.ConnectedStations[1].WeatherZone != null) { AddWord(OutWords, Line.ConnectedStations[1].WeatherZone.Name); } } }
/// <summary> /// Add a data element to the appropriate table /// </summary> /// <param name="Elem">The element to be added</param> public DataRow AddDataElement(MM_Element Elem) { try { //If we don't have a table with the proper name, add it in. DataTable FoundTable = Data.Tables[Elem.ElemType.Name]; if (FoundTable == null) { FoundTable = Data.Tables.Add(Elem.ElemType.Name); FoundTable.PrimaryKey = new DataColumn[] { FoundTable.Columns.Add("TEID", typeof(MM_Element)) }; } DataRow NewRow; if (!ElementsByTEID.TryGetValue(Elem.TEID, out NewRow)) { NewRow = FoundTable.NewRow(); NewRow["TEID"] = Elem; FoundTable.Rows.Add(NewRow); ElementsByTEID.Add(Elem.TEID, NewRow); } //Add in the substation column if (Elem is MM_Line) { MM_Line ThisLine = (Elem as MM_Line); UpdateRowData(NewRow, "From", typeof(String), ThisLine.ConnectedStations[0].DisplayName()); UpdateRowData(NewRow, "To", typeof(String), ThisLine.ConnectedStations[1].DisplayName()); } else if (Elem.Substation != null) { UpdateRowData(NewRow, "Substation", typeof(String), Elem.Substation.DisplayName()); } //Update the name column if (Elem is MM_Substation) { UpdateRowData(NewRow, "Name", typeof(String), (Elem as MM_Substation).DisplayName()); } else { UpdateRowData(NewRow, "Name", typeof(String), Elem.Name); } //Update voltage, if possible if (Elem is MM_Substation) { UpdateRowData(NewRow, "KV Levels", typeof(String), (Elem as MM_Substation).KVLevelList); } else if (Elem is MM_Transformer) { UpdateRowData(NewRow, "KV Levels", typeof(String), (Elem as MM_Transformer).KVLevelList); } else if (Elem.KVLevel != null) { UpdateRowData(NewRow, "KV Level", typeof(String), Elem.KVLevel.Name.Split(' ')[0]); } RefreshData(NewRow, Elem); return(NewRow); } catch (Exception) { return(null); } }
/// <summary> /// Determine our next question /// </summary> public void NextQuestion() { //First, determine what our current level should be, and by threshold move to the next level if needed MM_Training_Level FoundLevel; if (CurrentLevel == null) { PriorLevel = null; if (!Levels.TryGetValue(0, out FoundLevel)) { TrainingMode = enumTrainingMode.NotTraning; return; } else { CurrentLevel = FoundLevel; } } else if (LevelScore >= CurrentLevel.ExitThresholdScore && QuestionsRight >= CurrentLevel.NumberOfQuestions) { if (!Levels.TryGetValue(CurrentLevel.ID + 1, out FoundLevel)) { MessageTime = DateTime.Now; TrainingMode = enumTrainingMode.UserWon; return; } else { CurrentLevel = FoundLevel; } } else if (QuestionsWrong >= CurrentLevel.FailureThreshold) { MessageTime = DateTime.Now; TrainingMode = enumTrainingMode.UserFailed; return; } //Based on our question, determine our next if (PriorLevel != CurrentLevel) { PrepareLevel(); } //If we have no elements, assume we won if (AvailableElements.Length == 0) { TrainingMode = enumTrainingMode.UserWon; return; } //Pick random elements based on our needs TargetElement = AvailableElements[rnd.Next(0, AvailableElements.Length)]; if (TargetElement is MM_Line || TargetElement is MM_Substation) { } else { TargetElement = TargetElement.Substation; } //Now, handle our target element if (TargetElement is MM_Substation) { MM_Substation TargetSub = (MM_Substation)TargetElement; QuestionText = "Where is substation " + TargetSub.LongName + (String.Equals(TargetSub.LongName, TargetSub.Name, StringComparison.CurrentCultureIgnoreCase) ? "?" : " (" + TargetSub.Name + ")?"); } else if (TargetElement is MM_Line) { MM_Line TargetLine = (MM_Line)TargetElement; QuestionText = "Where is line " + TargetLine.Name + " (from " + TargetLine.Substation1.LongName + " to " + TargetLine.Substation2.LongName + ")?"; } else { QuestionText = "Where is " + TargetElement.ElemType.Name + " " + TargetElement.Name + "?"; } Data_Integration.ReportSystemLevelData(QuestionText); TrainingMode = enumTrainingMode.QuestionAsked; TimeQuestionPresented = DateTime.Now; }