private void TransformToTopologyElement(ResourceDescription modelEntity) { DMSType dmsType; dmsType = GetDMSTypeOfTopologyElement(modelEntity.Id); if (dmsType == DMSType.DISCRETE) { Measurement newDiscrete = GetPopulatedDiscreteMeasurement(modelEntity); Measurements.Add(newDiscrete.Id, newDiscrete); Provider.Instance.MeasurementProvider.AddDiscreteMeasurement(newDiscrete as DiscreteMeasurement); } else if (dmsType == DMSType.ANALOG) { Measurement newAnalog = GetPopulatedAnalogMeasurement(modelEntity); Measurements.Add(newAnalog.Id, newAnalog); Provider.Instance.MeasurementProvider.AddAnalogMeasurement(newAnalog as AnalogMeasurement); } else if (dmsType != DMSType.MASK_TYPE && dmsType != DMSType.BASEVOLTAGE) { ITopologyElement newElement = GetPopulatedElement(modelEntity); TopologyElements.Add(newElement.Id, newElement); if (dmsType == DMSType.ENERGYSOURCE) { EnergySources.Add(newElement.Id); } ElementConnections.Add(modelEntity.Id, (GetAllReferencedElements(modelEntity))); } }
public IMaxTree <ElementType> BuildMaxTree(ElementType[] element_array, IComparer <ElementType> element_value_comparer, ITopologyElement topology, int real_element_count, IProgressReporter reporter) { this.d_element_array = element_array; this.element_value_comparer = element_value_comparer; this.element_index_comparer = new ComparerArrayIndex <ElementType>(element_value_comparer, element_array); this.d_topology = topology; this.d_reporter = reporter; this.d_done = 0; this.d_elements_to_queued = new bool[d_element_array.Length]; this.d_neigbor_element_array = new int[d_topology.MaximumConnectivity]; this.d_fringe = new PriorityQueueC5 <int>(element_index_comparer); this.d_component_stack = new Stack <Tuple <ElementType, IList <int>, IList <MaxTreeNode <ElementType> > > >(); d_fringe.Enqueue(0); d_elements_to_queued[0] = true; // Build tree while (d_fringe.Count != 0) { Process(d_fringe.PeekLast()); } Tuple <ElementType, IList <int>, IList <MaxTreeNode <ElementType> > > component = d_component_stack.Pop(); MaxTreeNode <ElementType> bottom_level_node = new MaxTreeNode <ElementType>(component.Item1, component.Item2, component.Item3, element_value_comparer); return(new MaxTree <ElementType>(bottom_level_node, d_element_array.Length, real_element_count, element_value_comparer)); }
private async Task <ITopologyElement> CreateNoScadaMeasurementAsync(ITopologyElement element) { string verboseMessage = $"{baseLogString} entering CreateNoScadaMeasurement method."; Logger.LogVerbose(verboseMessage); DMSType dMSType = GetDMSTypeOfTopologyElement(element.Id); if (dMSType == DMSType.LOADBREAKSWITCH || dMSType == DMSType.BREAKER || dMSType == DMSType.FUSE || dMSType == DMSType.DISCONNECTOR) { ArtificalDiscreteMeasurement measurement = GetNoScadaDiscreteMeasurement(); element.Measurements.Add(measurement.Id, "SWITCH_STATUS"); measurement.ElementId = element.Id; var measurementProviderClient = MeasurementProviderClient.CreateClient(); await measurementProviderClient.AddDiscreteMeasurement(measurement); measurementProviderClient = MeasurementProviderClient.CreateClient(); await measurementProviderClient.AddMeasurementElementPair(measurement.Id, element.Id); } return(element); }
public IMaxTree <ElementType> BuildMaxTree(ElementType[] element_array, IComparer <ElementType> element_value_comparer, ITopologyElement topology, int real_element_count, IProgressReporter reporter) { this.d_element_array = element_array; this.element_value_comparer = element_value_comparer; this.element_index_comparer = new ComparerArrayIndex <ElementType>(element_value_comparer, element_array); this.d_topology = topology; this.d_elements_to_processed = new bool[d_element_array.Length]; this.d_neigbor_element_array = new int[d_topology.MaximumConnectivity]; this.d_fringe = new Stack <OrderedBag <int> >(); this.d_component_stack = new Stack <Tuple <ElementType, IList <int>, IList <MaxTreeNode <ElementType> > > >(); this.d_bottom_level_node = null; process(0); // build tree while (d_fringe.Count != 0) { if (d_fringe.Peek().Count == 0) { decrease_process_level(); // continue on a lower level } else { // otherwise keep on processing the fringe process(d_fringe.Peek().RemoveFirst()); } } return(new MaxTree <ElementType>(d_bottom_level_node, d_element_array.Length, real_element_count, element_value_comparer)); }
private void DeEnergizeElementsUnder(ITopologyElement element) { Stack <ITopologyElement> stack = new Stack <ITopologyElement>(); stack.Push(element); ITopologyElement nextElement; while (stack.Count > 0) { nextElement = stack.Pop(); nextElement.IsActive = false; if (nextElement is Field field) { foreach (var member in field.Members) { TurnOffAllMeasurement(member.Measurements); member.IsActive = false; } } TurnOffAllMeasurement(nextElement.Measurements); foreach (var child in nextElement.SecondEnd) { if (!reclosers.Contains(child.Id)) { stack.Push(child); } } } }
public Field(ITopologyElement firstElement) : base(++fieldNumber) { Members = new List <ITopologyElement>() { firstElement }; Mrid = $"F_{fieldNumber}"; Name = $"F_{fieldNumber}"; }
public void AddElement(ITopologyElement newElement) { if (!TopologyElements.ContainsKey(newElement.Id)) { TopologyElements.Add(newElement.Id, newElement); } else { //Logger.Instance.LogWarn($"Topology element with GID 0x{newElement.Id.ToString("X16")} is already added."); } }
private ITopology CalculateLoadFlowFromRecloser(ITopologyElement recloser, ITopology topology, Dictionary <long, float> loadOfFeeders) { long measurementGid = 0; if (recloser.Measurements.Count == 1) { //dogovor je da prekidaci imaju samo discrete measurement measurementGid = recloser.Measurements.First().Key; } else { logger.LogWarn($"[CalculateLoadFlowFromRecloser] Recloser with GID 0x{recloser.Id.ToString("X16")} does not have proper measurements."); } if (recloser.FirstEnd != null && recloser.SecondEnd.Count == 1) { if (recloser.FirstEnd.IsActive && !recloser.SecondEnd.First().IsActive) { if (IsElementEnergized(recloser, out float load)) { CalculateLoadFlowUpsideDown(recloser.SecondEnd.First(), recloser.Id, recloser.FirstEnd.Feeder, loadOfFeeders); } else { Thread thread = new Thread(() => CommandToRecloser(measurementGid, 0, CommandOriginType.CE_COMMAND, recloser)); thread.Start(); } } else if (!recloser.FirstEnd.IsActive && recloser.SecondEnd.First().IsActive) { if (IsElementEnergized(recloser, out float load)) { CalculateLoadFlowUpsideDown(recloser.FirstEnd, recloser.Id, recloser.SecondEnd.First().Feeder, loadOfFeeders); } else { Thread thread = new Thread(() => CommandToRecloser(measurementGid, 0, CommandOriginType.CE_COMMAND, recloser)); thread.Start(); } } else { //TODO: pitati asistente, da li da se prenese na Validate scadaCommanding.SendDiscreteCommand(measurementGid, 1, CommandOriginType.CE_COMMAND); recloser.IsActive = false; } } else { logger.LogDebug($"[CalculateLoadFlowFromRecloser] Recloser with GID 0x{recloser.Id.ToString("X16")} does not have both ends, or have more than one on one end."); } return(topology); }
public Feeder(ITopologyElement element) : base(element.Id) { Id = element.Id; Description = element.Description; Mrid = element.Mrid; Name = element.Name; NominalVoltage = element.NominalVoltage; FirstEnd = element.FirstEnd; SecondEnd = element.SecondEnd; DmsType = element.DmsType; Measurements = element.Measurements; IsRemote = element.IsRemote; IsActive = element.IsActive; }
private void ConnectTwoNodes(ITopologyElement newNode, ITopologyElement parent) { bool newElementIsField = TopologyHelper.Instance.GetElementTopologyStatus(newNode.Id) == TopologyStatus.Field; bool parentElementIsField = TopologyHelper.Instance.GetElementTopologyStatus(parent.Id) == TopologyStatus.Field; if (newElementIsField && !parentElementIsField) { var field = new Field(newNode); field.FirstEnd = parent; newNode.FirstEnd = parent; fields.Add(field); parent.SecondEnd.Add(field); } else if (newElementIsField && parentElementIsField) { try { GetField(parent.Id).Members.Add(newNode); newNode.FirstEnd = parent; parent.SecondEnd.Add(newNode); } catch (Exception) { string message = $"Element with GID 0x{parent.Id.ToString("X16")} has no field."; logger.LogDebug(message); throw new Exception(message); } } else if (!newElementIsField && parentElementIsField) { var field = GetField(parent.Id); if (field == null) { string message = $"Element with GID 0x{parent.Id.ToString("X16")} has no field."; logger.LogDebug(message); throw new Exception(message); } else { field.SecondEnd.Add(newNode); parent.SecondEnd.Add(newNode); newNode.FirstEnd = field; } } else { newNode.FirstEnd = parent; parent.SecondEnd.Add(newNode); } }
public bool GetElementByGid(long gid, out ITopologyElement topologyElement) { bool success = false; if (TopologyElements.ContainsKey(gid)) { topologyElement = TopologyElements[gid]; success = true; } else { topologyElement = null; } return(success); }
private void CreateNoScadaMeasurement(ITopologyElement element) { DMSType dMSType = GetDMSTypeOfTopologyElement(element.Id); if (dMSType == DMSType.LOADBREAKSWITCH || dMSType == DMSType.BREAKER || dMSType == DMSType.FUSE || dMSType == DMSType.DISCONNECTOR) { ArtificalDiscreteMeasurement measurement = GetNoScadaDiscreteMeasurement(); element.Measurements.Add(measurement.Id, "SWITCH_STATUS"); measurement.ElementId = element.Id; Provider.Instance.MeasurementProvider.AddDiscreteMeasurement(measurement); Provider.Instance.MeasurementProvider.AddMeasurementElementPair(measurement.Id, element.Id); } }
public Recloser(ITopologyElement element) : base(element.Id) { Id = element.Id; Description = element.Description; Mrid = element.Mrid; Name = element.Name; NominalVoltage = element.NominalVoltage; FirstEnd = element.FirstEnd; SecondEnd = element.SecondEnd; DmsType = element.DmsType; Measurements = element.Measurements; IsRemote = element.IsRemote; IsActive = element.IsActive; NoReclosing = element.NoReclosing; NumberOfTry = 0; MaxNumberOfTries = 3; }
private async Task DeEnergizeElementsUnder(ITopologyElement element) { string verboseMessage = $"{baseLogString} DeEnergizeElementsUnder method called => Element: {element?.Id:X16}."; Logger.LogVerbose(verboseMessage); Stack <ITopologyElement> stack = new Stack <ITopologyElement>(); stack.Push(element); ITopologyElement nextElement; while (stack.Count > 0) { nextElement = stack.Pop(); nextElement.IsActive = false; if (nextElement is Field field) { foreach (var member in field.Members) { await TurnOffAllMeasurement(member.Measurements); member.IsActive = false; } } await TurnOffAllMeasurement(nextElement.Measurements); foreach (var child in nextElement.SecondEnd) { if (!reclosers.Contains(child.Id)) { stack.Push(child); } } } }
public IMaxTree <ElementType> BuildMaxTree(ElementType[] element_array, IComparer <ElementType> element_value_comparer, ITopologyElement topology, int real_element_count) { return(BuildMaxTree(element_array, element_value_comparer, topology, real_element_count, null)); }
public MaxTreeAutoDual(IAlgebraReal <ElementType> algebra, IMaxTreeBuilder <ElementType> builder, ITopologyElement topology, ElementType[] element_values) { this.algebra = algebra; this.max_tree = builder.BuildMaxTree(element_values, new ComparerNatural <ElementType>(), topology, element_values.Length); this.min_tree = builder.BuildMaxTree(element_values, new ComparerNatural <ElementType>(true), topology, element_values.Length); this.element_values = ToolsCollection.Copy(element_values); }
private async Task CommandToRecloser(long measurementGid, int value, CommandOriginType originType, ITopologyElement recloser) { string verboseMessage = $"{baseLogString} CommandToRecloser method called."; Logger.LogVerbose(verboseMessage); if (recloser == null) { string message = $"{baseLogString} CommandToRecloser => NULL value has been passed instead of element."; Logger.LogError(message); throw new Exception(message); } if (!(recloser is Recloser)) { string message = $"{baseLogString} CommandToRecloser => Element with GID {recloser.Id:X16} is not a recloser."; Logger.LogError(message); throw new Exception(message); } Logger.LogDebug($"{baseLogString} CommandToRecloser => Enetring in sleep for 20 seconds."); await Task.Delay(recloserInterval); Logger.LogDebug($"{baseLogString} CommandToRecloser => Waking up after 20 seconds."); var topologyProviderClient = TopologyProviderClient.CreateClient(); int counter = await topologyProviderClient.GetRecloserCount(recloser.Id); if (((Recloser)recloser).MaxNumberOfTries > counter) { topologyProviderClient = TopologyProviderClient.CreateClient(); await topologyProviderClient.RecloserOpened(recloser.Id); Logger.LogDebug($"{baseLogString} CommandToRecloser => Calling SendDiscreteCommand method from measurement provider. Measurement GID: {measurementGid:X16}, Value: {value}, OriginType {originType}."); var measurementProviderClient = MeasurementProviderClient.CreateClient(); await measurementProviderClient.SendSingleDiscreteCommand(measurementGid, value, originType); Logger.LogDebug($"{baseLogString} CommandToRecloser => SendDiscreteCommand method has been successfully called."); } }
public static void GetShellRBA <RasterType>(IImageRaster <RasterType, bool> source, ITopologyElement topology, IImageRaster <RasterType, bool> target, bool border_is_shell) where RasterType : IRasterInteger { int[] element_neigbour_array = new int[topology.MaximumConnectivity]; for (int element_index = 0; element_index < source.Raster.ElementCount; element_index++) { if (source.GetElementValue(element_index)) { bool is_shell = false; topology.ElementNeighboursRBA(element_index, element_neigbour_array); foreach (int other_element_index in element_neigbour_array) { if (other_element_index != -1) { if (!source.GetElementValue(other_element_index)) { is_shell = true; } } else { if (border_is_shell) { is_shell = true; } } } if (is_shell) { target.SetElementValue(element_index, true); } } } }
private void ConnectTwoNodes(ITopologyElement newNode, ITopologyElement parent) { string verboseMessage = $"{baseLogString} ConnectTwoNodes method called. New node GID {newNode?.Id:X16}, Parent node GID {parent?.Id:X16}."; Logger.LogVerbose(verboseMessage); if (newNode == null) { string message = $"{baseLogString} ConnectTwoNodes => New node is null."; Logger.LogError(message); throw new Exception(message); } if (parent == null) { string message = $"{baseLogString} ConnectTwoNodes => Parent node is null."; Logger.LogError(message); throw new Exception(message); } bool newElementIsField = TopologyHelper.Instance.GetElementTopologyStatus(newNode.Id) == TopologyStatus.Field; bool parentElementIsField = TopologyHelper.Instance.GetElementTopologyStatus(parent.Id) == TopologyStatus.Field; if (newElementIsField && !parentElementIsField) { var field = new Field(newNode); field.FirstEnd = parent; newNode.FirstEnd = parent; fields.Add(field); parent.SecondEnd.Add(field); } else if (newElementIsField && parentElementIsField) { try { GetField(parent.Id).Members.Add(newNode); newNode.FirstEnd = parent; parent.SecondEnd.Add(newNode); } catch (Exception) { string message = $"{baseLogString} ConnectTwoNodes => Element with GID {parent.Id:X16} has no field."; Logger.LogError(message); throw new Exception(message); } } else if (!newElementIsField && parentElementIsField) { var field = GetField(parent.Id); if (field == null) { string message = $"{baseLogString} ConnectTwoNodes => Element with GID {parent.Id:X16} has no field."; Logger.LogError(message); throw new Exception(message); } else { field.SecondEnd.Add(newNode); parent.SecondEnd.Add(newNode); newNode.FirstEnd = field; } } else { newNode.FirstEnd = parent; parent.SecondEnd.Add(newNode); } }
private async Task <Tuple <bool, float> > IsElementEnergized(ITopologyElement element) { string verboseMessage = $"{baseLogString} IsElementEnergized method called => Element: {element?.Id:X16}."; Logger.LogVerbose(verboseMessage); float load = 0; bool pastState = element.IsActive; element.IsActive = true; foreach (var measurement in element.Measurements) { if ((DMSType)ModelCodeHelper.ExtractTypeFromGlobalId(measurement.Key) == DMSType.DISCRETE || measurement.Key < 10000) { Logger.LogDebug($"{baseLogString} IsElementEnergized => Getting discrete value of {measurement.Key:X16} from measurement provider."); var measurementProviderClient = MeasurementProviderClient.CreateClient(); bool isOpen = await measurementProviderClient.GetDiscreteValue(measurement.Key); Logger.LogDebug($"{baseLogString} IsElementEnergized => Discrete value of {measurement.Key:X16} has been delivered successfully. Result is [{isOpen}]."); // Value je true ako je prekidac otvoren, tada je element neaktivan element.IsActive = !isOpen; break; } } if (element.IsActive) { if (!pastState) { await TurnOnAllMeasurement(element.Measurements); } List <AnalogMeasurement> analogMeasurements = await GetMeasurements(element.Measurements); if (element.DmsType.Equals(DMSType.SYNCHRONOUSMACHINE.ToString())) { if (!syncMachines.ContainsKey(element.Id)) { syncMachines.Add(element.Id, element); } } else { if (element.IsRemote) { float power = 0; float voltage = 0; foreach (var analogMeasurement in analogMeasurements) { if (analogMeasurement.GetMeasurementType().Equals(AnalogMeasurementType.POWER.ToString())) { power = analogMeasurement.GetCurrentValue(); } else if (analogMeasurement.GetMeasurementType().Equals(AnalogMeasurementType.VOLTAGE.ToString())) { voltage = analogMeasurement.GetCurrentValue(); } } if (power != 0 && voltage != 0) { load = (float)Math.Round(power / voltage); } } else if (element is EnergyConsumer consumer) { if (dailyCurves.TryGetValue(EnergyConsumerTypeToDailyCurveConverter.GetDailyCurveType(consumer.Type), out DailyCurve curve)) { load = (float)Math.Round(curve.GetValue((short)DateTime.Now.Hour) * 1000 / 220); } } } } return(new Tuple <bool, float>(element.IsActive, load)); }
private async Task SyncMachine(ITopologyElement element, Dictionary <long, float> loadOfFeeders) { string verboseMessage = $"{baseLogString} SyncMachine method called. Element with GID {element?.Id:X16}"; Logger.LogVerbose(verboseMessage); if (element == null) { string message = $"{baseLogString} UpdateLoadFlow => Element is null."; Logger.LogError(message); throw new Exception(message); } if (!(element is SynchronousMachine)) { string message = $"{baseLogString} UpdateLoadFlow => Element is not SynchronousMachine."; Logger.LogError(message); throw new Exception(message); } AnalogMeasurement powerMeasurement = null; AnalogMeasurement voltageMeasurement = null; if (element.Feeder != null) { if (loadOfFeeders.TryGetValue(element.Feeder.Id, out float feederLoad)) { float machineCurrentChange; if (feederLoad > 36) { float improvementFactor = feederLoad - 36; machineCurrentChange = (((SynchronousMachine)element).Capacity >= improvementFactor) ? improvementFactor : ((SynchronousMachine)element).Capacity; } else { machineCurrentChange = 0; } foreach (var meas in element.Measurements) { if (meas.Value.Equals(AnalogMeasurementType.POWER.ToString())) { Logger.LogDebug($"{baseLogString} UpdateLoadFlow => Calling GetAnalogMeasurement method from measurement provider. Measurement GID {meas.Key:X16}."); var measurementProviderClient = MeasurementProviderClient.CreateClient(); powerMeasurement = await measurementProviderClient.GetAnalogMeasurement(meas.Key); Logger.LogDebug($"{baseLogString} UpdateLoadFlow => GetAnalogMeasurement method called successfully."); if (powerMeasurement == null) { Logger.LogError($"{baseLogString} UpdateLoadFlow => Synchronous machine with GID {element.Id:X16} does not have POWER measurement."); } } if (meas.Value.Equals(AnalogMeasurementType.VOLTAGE.ToString())) { Logger.LogDebug($"{baseLogString} UpdateLoadFlow => Calling GetAnalogMeasurement method from measurement provider. Measurement GID {meas.Key:X16}."); var measurementProviderClient = MeasurementProviderClient.CreateClient(); voltageMeasurement = await measurementProviderClient.GetAnalogMeasurement(meas.Key); Logger.LogDebug($"{baseLogString} UpdateLoadFlow => GetAnalogMeasurement method called successfully."); if (voltageMeasurement == null) { Logger.LogError($"{baseLogString} UpdateLoadFlow => Synchronous machine with GID {element.Id:X16} does not have VOLTAGE measurement."); } } } if (powerMeasurement != null && voltageMeasurement != null) { float newNeededPower = machineCurrentChange * voltageMeasurement.GetCurrentValue(); float newSMPower = (((SynchronousMachine)element).Capacity >= newNeededPower) ? newNeededPower : ((SynchronousMachine)element).Capacity; Logger.LogDebug($"{baseLogString} UpdateLoadFlow => Calling SendAnalogCommand method from measurement provider. Measurement GID {powerMeasurement.Id:X16}, Value {newSMPower}."); var measurementProviderClient = MeasurementProviderClient.CreateClient(); await measurementProviderClient.SendSingleAnalogCommand(powerMeasurement.Id, newSMPower, CommandOriginType.CE_COMMAND); Logger.LogDebug($"{baseLogString} UpdateLoadFlow => SendAnalogCommand method called successfully."); Dictionary <long, AnalogModbusData> data = new Dictionary <long, AnalogModbusData>(1) { { powerMeasurement.Id, new AnalogModbusData(newSMPower, AlarmType.NO_ALARM, powerMeasurement.Id, CommandOriginType.CE_COMMAND) } }; Logger.LogDebug($"{baseLogString} UpdateLoadFlow => Calling UpdateAnalogMeasurement method from measurement provider."); measurementProviderClient = MeasurementProviderClient.CreateClient(); await measurementProviderClient.UpdateAnalogMeasurement(data); Logger.LogDebug($"{baseLogString} UpdateLoadFlow => UpdateAnalogMeasurement method called successfully."); loadOfFeeders[element.Feeder.Id] -= newSMPower / voltageMeasurement.GetCurrentValue(); } else { Logger.LogError($"{baseLogString} UpdateLoadFlow => Synchronous machine with GID {element.Id:X16} does not have measurements for calculating CURRENT."); } } } else { Logger.LogError($"{baseLogString} UpdateLoadFlow => Synchronous machine with GID {element.Id:X16} does not belond to any feeder."); } }
public Tuple <int[, ], float[, ]> build_super_shape(float[] image, int neigbour_count, ITopologyElement topology) { int[,] neigbour_elements = new int[image.Length, neigbour_count]; float[,] neigbour_distances = new float[image.Length, neigbour_count]; Parallel.For(0, image.Length, index_element => { //int index_current = 0; //int index_fringe_end = 0; for (int i = 0; i < neigbour_count; i++) { } }); return(new Tuple <int[, ], float[, ]>(neigbour_elements, neigbour_distances)); }
private void SyncMachine(ITopologyElement element, Dictionary <long, float> loadOfFeeders) { AnalogMeasurement powerMeasurement = null; AnalogMeasurement voltageMeasurement = null; if (element.Feeder != null) { if (loadOfFeeders.TryGetValue(element.Feeder.Id, out float feederLoad)) { float machineCurrentChange; if (feederLoad > 36) { float improvementFactor = feederLoad - 36; machineCurrentChange = (((SynchronousMachine)element).Capacity >= improvementFactor) ? improvementFactor : ((SynchronousMachine)element).Capacity; } else { machineCurrentChange = 0; } foreach (var meas in element.Measurements) { if (meas.Value.Equals(AnalogMeasurementType.POWER.ToString())) { if (!Provider.Instance.MeasurementProvider.TryGetAnalogMeasurement(meas.Key, out powerMeasurement)) { logger.LogError($"[Load flow] Synchronous machine with GID 0x{element.Id:X16} does not have POWER measurement."); } } if (meas.Value.Equals(AnalogMeasurementType.VOLTAGE.ToString())) { if (!Provider.Instance.MeasurementProvider.TryGetAnalogMeasurement(meas.Key, out voltageMeasurement)) { logger.LogError($"[Load flow] Synchronous machine with GID 0x{element.Id:X16} does not have VOLTAGE measurement."); } } } if (powerMeasurement != null && voltageMeasurement != null) { float newNeededPower = machineCurrentChange * voltageMeasurement.GetCurrentValue(); float newSMPower = (((SynchronousMachine)element).Capacity >= newNeededPower) ? newNeededPower : ((SynchronousMachine)element).Capacity; scadaCommanding.SendAnalogCommand(powerMeasurement.Id, newSMPower, CommandOriginType.CE_COMMAND); Dictionary <long, AnalogModbusData> data = new Dictionary <long, AnalogModbusData>(1) { { powerMeasurement.Id, new AnalogModbusData(newSMPower, AlarmType.NO_ALARM, powerMeasurement.Id, CommandOriginType.CE_COMMAND) } }; Provider.Instance.MeasurementProvider.UpdateAnalogMeasurement(data); loadOfFeeders[element.Feeder.Id] -= newSMPower / voltageMeasurement.GetCurrentValue(); } else { logger.LogError($"[Load flow] Synchronous machine with GID 0x{element.Id:X16} does not have CURRENT measurement."); } } } else { logger.LogWarn($"[Load flow] Synchronous machine with GID 0x{element.Id:X16} does not belond to any feeder."); } }
private void CommandToRecloser(long measurementGid, int value, CommandOriginType originType, ITopologyElement recloser) { Thread.Sleep(10000); if (!((Recloser)recloser).IsReachedMaximumOfTries()) { scadaCommanding.SendDiscreteCommand(measurementGid, value, originType); ((Recloser)recloser).NumberOfTry++; } }
private void CalculateLoadFlowUpsideDown(ITopologyElement element, long sourceElementGid, ITopologyElement feeder, Dictionary <long, float> loadOfFeeders) { Stack <Tuple <ITopologyElement, long> > stack = new Stack <Tuple <ITopologyElement, long> >(); stack.Push(new Tuple <ITopologyElement, long>(element, sourceElementGid)); Tuple <ITopologyElement, long> tuple; ITopologyElement nextElement; long sourceGid; while (stack.Count > 0) { tuple = stack.Pop(); nextElement = tuple.Item1; sourceGid = tuple.Item2; if (IsElementEnergized(nextElement, out float load)) { if (!nextElement.DmsType.Equals(DMSType.ENERGYCONSUMER.ToString()) && nextElement.FirstEnd.Id != sourceGid) { stack.Push(new Tuple <ITopologyElement, long>(nextElement.FirstEnd, nextElement.Id)); } foreach (var child in nextElement.SecondEnd) { if (child.Id != sourceGid) { stack.Push(new Tuple <ITopologyElement, long>(child, nextElement.Id)); } } if (feeder != null) { if (loadOfFeeders.ContainsKey(feeder.Id)) { loadOfFeeders[feeder.Id] += load; } else { loadOfFeeders.Add(feeder.Id, load); } } } else { if (nextElement.DmsType.Equals(DMSType.FUSE.ToString())) { DeEnergizeElementsUnder(nextElement); } else { foreach (var child in nextElement.SecondEnd) { if (child.Id != sourceGid) { stack.Push(new Tuple <ITopologyElement, long>(child, nextElement.Id)); } } } } } }
private async Task TransformToTopologyElementAsync(ResourceDescription modelEntity) { string verboseMessage = $"{baseLogString} entering TransformToTopologyElement method."; Logger.LogVerbose(verboseMessage); DMSType dmsType; dmsType = GetDMSTypeOfTopologyElement(modelEntity.Id); if (dmsType == DMSType.DISCRETE) { Measurement newDiscrete = await GetPopulatedDiscreteMeasurement(modelEntity); if (!await Measurements.ContainsKeyAsync(newDiscrete.Id)) { await Measurements.SetAsync(newDiscrete.Id, newDiscrete); //contains moze da bude false, a da kad doje ova linija na red, da vrednost bude popunjena, zato SetAsync, ali onda je sam if suvisan (ne znam da li je kljucan za neku logiku...) } var measurementProviderClient = MeasurementProviderClient.CreateClient(); await measurementProviderClient.AddDiscreteMeasurement(newDiscrete as DiscreteMeasurement); } else if (dmsType == DMSType.ANALOG) { Measurement newAnalog = await GetPopulatedAnalogMeasurement(modelEntity); if (!await Measurements.ContainsKeyAsync(newAnalog.Id)) { await Measurements.SetAsync(newAnalog.Id, newAnalog); //contains moze da bude false, a da kad doje ova linija na red, da vrednost bude popunjena, zato SetAsync, ali onda je sam if suvisan (ne znam da li je kljucan za neku logiku...) } var measurementProviderClient = MeasurementProviderClient.CreateClient(); await measurementProviderClient.AddAnalogMeasurement(newAnalog as AnalogMeasurement); } else if (dmsType != DMSType.MASK_TYPE && dmsType != DMSType.BASEVOLTAGE) { ITopologyElement newElement = await GetPopulatedElement(modelEntity); //lock (syncObj) //{ if (!await TopologyElements.ContainsKeyAsync(newElement.Id)) { await TopologyElements.SetAsync(newElement.Id, newElement); //contains moze da bude false, a da kad doje ova linija na red, da vrednost bude popunjena, zato SetAsync, ali onda je sam if suvisan (ne znam da li je kljucan za neku logiku...) } else { Logger.LogDebug($"{baseLogString} TransformToTopologyElementAsync => TopologyElements contain key {newElement.Id:X16}"); } //} if (dmsType == DMSType.ENERGYSOURCE) { var energySourcesResult = await EnergySources.TryGetValueAsync(ReliableDictionaryNames.EnergySources); if (energySourcesResult.HasValue) { var energySources = energySourcesResult.Value; energySources.Add(newElement.Id); await EnergySources.SetAsync(ReliableDictionaryNames.EnergySources, energySources); } else { Logger.LogWarning($"{baseLogString} Reliable collection '{ReliableDictionaryNames.EnergySources}' was not defined yet. Handling..."); await EnergySources.SetAsync(ReliableDictionaryNames.EnergySources, new List <long>() { newElement.Id }); } } //lock (syncObj) //{ if (!await ElementConnections.ContainsKeyAsync(modelEntity.Id)) { await ElementConnections.SetAsync(modelEntity.Id, await GetAllReferencedElements(modelEntity)); //contains moze da bude false, a da kad doje ova linija na red, da vrednost bude popunjena, zato SetAsync, ali onda je sam if suvisan (ne znam da li je kljucan za neku logiku...) } else { Logger.LogDebug($"{baseLogString} TransformToTopologyElementAsync => ElementConnections contain key {modelEntity.Id:X16}"); } //} } }
private async Task <TopologyModel> CalculateLoadFlowFromRecloser(ITopologyElement recloser, TopologyModel topology, Dictionary <long, float> loadOfFeeders) { string verboseMessage = $"{baseLogString} CalculateLoadFlowFromRecloser method called. Element with GID {recloser?.Id:X16}."; Logger.LogVerbose(verboseMessage); if (recloser == null) { string message = $"{baseLogString} CalculateLoadFlowUpsideDown => NULL value has been passed instead of recloser."; Logger.LogError(message); throw new Exception(message); } if (topology == null) { string message = $"{baseLogString} CalculateLoadFlowUpsideDown => NULL value has been passed instead of topology."; Logger.LogError(message); throw new Exception(message); } long measurementGid = 0; if (recloser.Measurements.Count == 1) { //dogovor je da prekidaci imaju samo discrete measurement measurementGid = recloser.Measurements.First().Key; } else { Logger.LogWarning($"{baseLogString} CalculateLoadFlowUpsideDown => Recloser with GID {recloser.Id:X16} does not have proper measurements."); } bool isEnergized = false; if (recloser.FirstEnd != null && recloser.SecondEnd.Count == 1) { if (recloser.FirstEnd.IsActive && !recloser.SecondEnd.First().IsActive) { Tuple <bool, float> tuple = await IsElementEnergized(recloser); isEnergized = tuple.Item1; float load = tuple.Item2; if (isEnergized) { await CalculateLoadFlowUpsideDown(recloser.SecondEnd.First(), recloser.Id, recloser.FirstEnd.Feeder, loadOfFeeders); } else if (!recloser.IsActive) { Thread thread = new Thread(async() => await CommandToRecloser(measurementGid, (int)DiscreteCommandingType.CLOSE, CommandOriginType.CE_COMMAND, recloser)); thread.Start(); } } else if (!recloser.FirstEnd.IsActive && recloser.SecondEnd.First().IsActive) { Tuple <bool, float> tuple = await IsElementEnergized(recloser); isEnergized = tuple.Item1; float load = tuple.Item2; if (isEnergized) { await CalculateLoadFlowUpsideDown(recloser.FirstEnd, recloser.Id, recloser.SecondEnd.First().Feeder, loadOfFeeders); } else if (!recloser.IsActive) { Thread thread = new Thread(async() => await CommandToRecloser(measurementGid, (int)DiscreteCommandingType.CLOSE, CommandOriginType.CE_COMMAND, recloser)); thread.Start(); } } else if (recloser.IsActive) { Logger.LogDebug($"{baseLogString} TurnOnAllMeasurement => Calling SendDiscreteCommand method from measurement provider. Measurement GID {measurementGid:X16}, Value 1."); var measurementProviderClient = MeasurementProviderClient.CreateClient(); await measurementProviderClient.SendSingleDiscreteCommand(measurementGid, (int)DiscreteCommandingType.OPEN, CommandOriginType.CE_COMMAND); Logger.LogDebug($"{baseLogString} TurnOnAllMeasurement => SendDiscreteCommand method from measurement provider successfully finished."); recloser.IsActive = false; } } else { Logger.LogDebug($"{baseLogString} TurnOnAllMeasurement => Recloser with GID {recloser.Id:X16} does not have both ends, or have more than one on one end."); } return(topology); }
private async Task CalculateLoadFlowUpsideDown(ITopologyElement element, long sourceElementGid, ITopologyElement feeder, Dictionary <long, float> loadOfFeeders) { string verboseMessage = $"{baseLogString} CalculateLoadFlowUpsideDown method called. Element with GID {element?.Id:X16}, Source GID {sourceElementGid}."; Logger.LogVerbose(verboseMessage); if (element == null) { string message = $"{baseLogString} CalculateLoadFlowUpsideDown => NULL value has been passed instead of element."; Logger.LogError(message); throw new Exception(message); } if (feeder == null) { string message = $"{baseLogString} CalculateLoadFlowUpsideDown => NULL value has been passed instead of feeder."; Logger.LogError(message); throw new Exception(message); } Stack <Tuple <ITopologyElement, long> > stack = new Stack <Tuple <ITopologyElement, long> >(); stack.Push(new Tuple <ITopologyElement, long>(element, sourceElementGid)); Tuple <ITopologyElement, long> tuple; ITopologyElement nextElement; long sourceGid; while (stack.Count > 0) { tuple = stack.Pop(); nextElement = tuple.Item1; sourceGid = tuple.Item2; Tuple <bool, float> resTuple = await IsElementEnergized(nextElement); bool isEnergized = resTuple.Item1; float load = resTuple.Item2; if (isEnergized) { if (!nextElement.DmsType.Equals(DMSType.ENERGYCONSUMER.ToString()) && nextElement.FirstEnd.Id != sourceGid) { stack.Push(new Tuple <ITopologyElement, long>(nextElement.FirstEnd, nextElement.Id)); } foreach (var child in nextElement.SecondEnd) { if (child.Id != sourceGid) { stack.Push(new Tuple <ITopologyElement, long>(child, nextElement.Id)); } } if (feeder != null) { if (loadOfFeeders.ContainsKey(feeder.Id)) { loadOfFeeders[feeder.Id] += load; } else { loadOfFeeders.Add(feeder.Id, load); } } } else { if (nextElement.DmsType.Equals(DMSType.FUSE.ToString())) { await DeEnergizeElementsUnder(nextElement); } else { foreach (var child in nextElement.SecondEnd) { if (child.Id != sourceGid) { stack.Push(new Tuple <ITopologyElement, long>(child, nextElement.Id)); } } } } } }
public async Task <TopologyModel> CreateGraphTopology(long firstElementGid, string whoIsCalling) { Logger.LogVerbose($"{baseLogString} CreateGraphTopology method called, by {whoIsCalling}."); ITopologyElement currentFider = null; Logger.LogDebug($"{baseLogString} CreateGraphTopology => Calling GetElementModels method from model provider."); var modelProviderClient = CeModelProviderClient.CreateClient(); var dict = await modelProviderClient.GetElementModels(); elements = TransformDictionary(dict); Logger.LogDebug($"{baseLogString} CreateGraphTopology => GetElementModels method from model provider has been called successfully."); Logger.LogDebug($"{baseLogString} CreateGraphTopology => Calling GetConnections method from model provider."); modelProviderClient = CeModelProviderClient.CreateClient(); connections = await modelProviderClient.GetConnections(); Logger.LogDebug($"{baseLogString} CreateGraphTopology => GetConnections method from model provider has been called successfully."); Logger.LogDebug($"{baseLogString} CreateGraphTopology => Calling GetReclosers method from model provider."); modelProviderClient = CeModelProviderClient.CreateClient(); reclosers = await modelProviderClient.GetReclosers(); Logger.LogDebug($"{baseLogString} CreateGraphTopology => GetReclosers method from model provider has been called successfully."); Logger.LogDebug($"{baseLogString} CreateGraphTopology => Creating topology from first element with GID {firstElementGid:X16} started."); visited = new HashSet <long>(); stack = new Stack <long>(); fields = new List <Field>(); TopologyModel topology = new TopologyModel { FirstNode = firstElementGid }; try { stack.Push(firstElementGid); ITopologyElement currentElement; long currentElementId = 0; while (stack.Count > 0) { currentElementId = stack.Pop(); if (!visited.Contains(currentElementId)) { visited.Add(currentElementId); } if (!elements.TryGetValue(currentElementId, out currentElement)) { string message = $"{baseLogString} CreateGraphTopology => Failed to build topology.Topology does not contain element with GID {currentElementId:X16}."; Logger.LogError(message); return(topology); //throw new Exception(message); } List <long> referencedElements = GetReferencedElementsWithoutIgnorables(currentElementId); foreach (var element in referencedElements) { if (elements.TryGetValue(element, out ITopologyElement newNode)) { if (!reclosers.Contains(element)) { ConnectTwoNodes(newNode, currentElement); stack.Push(element); } else { currentElement.SecondEnd.Add(newNode); if (newNode.FirstEnd == null) { newNode.FirstEnd = currentElement; } else { newNode.SecondEnd.Add(currentElement); } if (!topology.TopologyElements.ContainsKey(newNode.Id)) { topology.AddElement(newNode); } } } else { Logger.LogError($"{baseLogString} CreateGraphTopology => Element with GID {element:X16} does not exist in collection of elements."); } } if (currentElement is Feeder) { currentFider = currentElement; } else { currentElement.Feeder = currentFider; } topology.AddElement(currentElement); } foreach (var field in fields) { topology.AddElement(field); } //long size = 0; //using (Stream stream = new MemoryStream()) //{ // BinaryFormatter formatter = new BinaryFormatter(); // formatter.Serialize(stream, topology); // size = stream.Length; //} //using (FileStream writer = new FileStream(@"E:\LogFiles\Topology.txt", FileMode.OpenOrCreate)) //{ // DataContractSerializer serializer = new DataContractSerializer(topology.GetType()); // serializer.WriteObject(writer, topology); //} } catch (Exception e) { Logger.LogError($"{baseLogString} Uhvacen eksepsn. {e.Message} {e.StackTrace}"); } Logger.LogDebug($"{baseLogString} CreateGraphTopology => Topology successfully created."); return(topology); }
private bool IsElementEnergized(ITopologyElement element, out float load) { load = 0; bool pastState = element.IsActive; element.IsActive = true; foreach (var measurement in element.Measurements) { if ((DMSType)ModelCodeHelper.ExtractTypeFromGlobalId(measurement.Key) == DMSType.DISCRETE || measurement.Key < 10000) { // Value je true ako je prekidac otvoren, tada je element neaktivan element.IsActive = !Provider.Instance.MeasurementProvider.GetDiscreteValue(measurement.Key); break; } } if (element.IsActive) { if (!pastState) { TurnOnAllMeasurement(element.Measurements); } var analogMeasurements = GetMeasurements(element.Measurements); if (element.DmsType.Equals(DMSType.SYNCHRONOUSMACHINE.ToString())) { if (!syncMachines.ContainsKey(element.Id)) { syncMachines.Add(element.Id, element); } } else { if (element.IsRemote) { float power = 0; float voltage = 0; foreach (var analogMeasurement in analogMeasurements) { if (analogMeasurement.GetMeasurementType().Equals(AnalogMeasurementType.POWER.ToString())) { power = analogMeasurement.GetCurrentValue(); } else if (analogMeasurement.GetMeasurementType().Equals(AnalogMeasurementType.VOLTAGE.ToString())) { voltage = analogMeasurement.GetCurrentValue(); } } if (power != 0 && voltage != 0) { load = (float)Math.Round(power / voltage); } } else if (element is EnergyConsumer consumer) { if (dailyCurves.TryGetValue(EnergyConsumerTypeToDailyCurveConverter.GetDailyCurveType(consumer.Type), out DailyCurve curve)) { load = (float)Math.Round(curve.GetValue((short)DateTime.Now.Hour) * 1000 / 220); } } } } return(element.IsActive); }