public SynchronousMachineViewModel(SynchronousMachine synchronousMachine, SubstationViewModel parentSubstation) : base(parentSubstation, false) { _synchronousMachine = synchronousMachine; if (synchronousMachine.FuelType == FTN.Common.FuelType.Sun) { SynchronousMachineIcon = @"../Images/SolarPanel.png"; } else if (synchronousMachine.FuelType == FTN.Common.FuelType.Wind) { SynchronousMachineIcon = @"../Images/Windmill.png"; } if (synchronousMachine.FuelType == FTN.Common.FuelType.Sun) { ReactiveVisibility = Visibility.Collapsed; } else { ReactiveVisibility = Visibility.Visible; } ActivePowerCommand = new RelayCommand(() => ExecuteActivePowerCommand()); ReactivePowerCommand = new RelayCommand(() => ExecuteReactivePowerCommand()); }
/// <summary> /// Calculates forecast for certain der object /// </summary> /// <param name="der"></param> /// <returns>Forecast object for certain der</returns> public ForecastObject HourlyForecastForDer(long derGID) { LogHelper.Log(LogTarget.File, LogService.CalculationEngineForecast, " INFO - CalculationEngineForecast.cs - Get hourly forecast for: " + derGID); SynchronousMachine der = model.DersOriginal.Where(o => o.GlobalId.Equals(derGID)).FirstOrDefault(); ForecastObject retValue = new ForecastObject(); lock (lockObj) { ForecastObject forecast = model.ForecastListOfDers.Where(o => o.DerGID.Equals(der.GlobalId)).FirstOrDefault(); DateTime start = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 0, 0, 0); DateTime end = start.AddDays(1); start = start.AddHours(DateTime.Now.Hour); retValue.DerGID = forecast.DerGID; retValue.HourlyP = forecast.HourlyP.Where(o => o.Timestamp >= start.Ticks && o.Timestamp <= end.Ticks).ToList(); retValue.HourlyQ = forecast.HourlyQ.Where(o => o.Timestamp >= start.Ticks && o.Timestamp <= end.Ticks).ToList(); retValue.HourlyP = CopyList(retValue.HourlyP); retValue.HourlyQ = CopyList(retValue.HourlyQ); UpdateForecastDataDer(retValue); } return(retValue); }
public List <SynchronousMachine> GetDERs(long gid) { List <SynchronousMachine> retVal; List <Substation> substations = new List <Substation>(); switch (((DMSType)ModelCodeHelper.ExtractTypeFromGlobalId(gid))) { case DMSType.REGION: List <SubGeographicalRegion> subRegions = GetSubRegionsForRegion(gid); foreach (SubGeographicalRegion subRegion in subRegions) { substations.AddRange(GetSubstationsForSubRegion(subRegion.GlobalId)); } break; case DMSType.SUBREGION: substations = GetSubstationsForSubRegion(gid); break; case DMSType.SUBSTATION: substations.Add(new Substation(gid)); break; case DMSType.SYNCMACHINE: SynchronousMachine sm = GetSyncMachineByGid(gid); return(new List <SynchronousMachine>() { sm }); } retVal = GetSynchronousMachineForSubstations(substations); return(retVal); }
private void DataAcquisition() { while (true) { LogHelper.Log(LogTarget.File, LogService.SCADACrunching, " INFO - SCADACrunching.cs - Data acquisition, new measurement ciclus."); timestamp = DateTime.Now; lock (SCADAModel.Instance.Lock2PC) { foreach (var analogValue in scadaModel.AnalogValues) { var value = client.ReadHoldingRegisters2(analogValue.Address, 1); SynchronousMachine syncMachine = adapter.GetSyncMachineByGid(analogValue.SynchronousMachine); if (syncMachine == null) { LogHelper.Log(LogTarget.File, LogService.SCADACrunching, " ERROR - SCADACrunching.cs - Data acquisition, Synchronous machine is not assigned to analog value."); throw new Exception("Synchronous machine is not assigned to analog value."); } analogValue.Value = RawValuesConverter.ConvertRange(value[0], RAW_MIN, RAW_MAX, EGU_MIN, EGU_MAX); analogValue.Timestamp = timestamp.Ticks; } SCADASubscriber.Instance.NotifySubscribers(DMSType.ANALOGVALUE); } Thread.Sleep(3000); } }
/// <summary> /// Returns all AOR Areas with full information /// </summary> /// <param name="areaGid"></param> /// <returns></returns> public List <AORCachedGroup> GetAORGroupsWithSmInfo() // LEFT TO DO { int iteratorId = 0; int resourcesLeft = 0; long gid = 0; // vrati se int numberOfResources = 500; Association association = new Association(ModelCode.AOR_GROUP_SYNCMACHINES, 0, false); List <AORGroup> aorGroups = GetAORGroups(); List <AORCachedGroup> resultIds = new List <AORCachedGroup>(aorGroups.Count); List <SynchronousMachine> syncMachines = null; try { List <ModelCode> properties = modelResourcesDesc.GetAllPropertyIds(ModelCode.SYNCMACHINE); foreach (var aorGroup in aorGroups) { iteratorId = GdaQueryProxy.GetRelatedValues(aorGroup.GlobalId, properties, association); resourcesLeft = GdaQueryProxy.IteratorResourcesLeft(iteratorId); syncMachines = new List <SynchronousMachine>(aorGroup.SynchronousMachines.Count); while (resourcesLeft > 0) { List <ResourceDescription> rds = GdaQueryProxy.IteratorNext(numberOfResources, iteratorId); foreach (ResourceDescription rd in rds) { SynchronousMachine tempSM = new SynchronousMachine(rd.Id); syncMachines.Add(tempSM.ConvertFromRD(rd)); } resourcesLeft = GdaQueryProxy.IteratorResourcesLeft(iteratorId); } resultIds.Add(new AORCachedGroup(aorGroup.Name, syncMachines)); } GdaQueryProxy.IteratorClose(iteratorId); CommonTrace.WriteTrace(CommonTrace.TraceError, "Getting extent values method (GetAORGroupsWithSmInfo) successfully finished."); } catch (Exception e) { string message = string.Format("Getting related values method failed for sourceGlobalId = {0} and association (propertyId = {1}, type = {2}). Reason: {3}", gid, association.PropertyId, association.Type, e.Message); Console.WriteLine(message); CommonTrace.WriteTrace(CommonTrace.TraceError, message); } return(resultIds); }
/// <summary> /// Gets available Active or Reactive power, based on DERs' flexibities /// </summary> /// <param name="gid">Gid of region, subregion or entire network </param> /// <param name="demandedValue"> Demanded increase</param> /// <param name="anaValues"> List of analog values </param> /// <param name="powerType"> Power type (active or reactive) </param> /// <returns></returns> public float GetAvailablePower(long gid, float demandedValue, List <AnalogValue> anaValues, PowerType powerType) { LogHelper.Log(LogTarget.File, LogService.CalculationEngineDistributer, " INFO - CalculationEngineDistributer.cs - Get available Active or Reactive power, based on DERs' flexibities for gid: " + gid); float availableSum = 0; float availableDERReserve = 0; float smFlexibility = 0; SynchronousMachine syncMachine = null; List <SynchronousMachine> syncMachines = RDAdapter.GetDERs(gid); foreach (var aValue in anaValues) { if (aValue.PowerType != powerType) { continue; } syncMachine = syncMachines.Find(sm => sm.GlobalId == aValue.SynchronousMachine); switch (powerType) { case PowerType.Active: availableDERReserve = syncMachine.MaxP - aValue.Value; smFlexibility = syncMachine.DERFlexibilityP; break; case PowerType.Reactive: availableDERReserve = syncMachine.MaxQ - aValue.Value; smFlexibility = syncMachine.DERFlexibilityQ; break; default: return(-1); } if (smFlexibility <= availableDERReserve) { availableSum += smFlexibility; } else { availableSum += availableDERReserve; } } return(availableSum); }
/// <summary> /// Creates entity for specified global ID inside the container. /// </summary> /// <param name="globalId">Global ID of the entity for insert</param> /// <returns>Created entity (identified object).</returns> public IdentifiedObject CreateEntity(long globalId) { short type = ModelCodeHelper.ExtractTypeFromGlobalId(globalId); IdentifiedObject io = null; switch ((DMSType)type) { case DMSType.REGION: io = new GeographicalRegion(globalId); break; case DMSType.SUBREGION: io = new SubGeographicalRegion(globalId); break; case DMSType.SUBSTATION: io = new Substation(globalId); break; case DMSType.SYNCMACHINE: io = new SynchronousMachine(globalId); dersCopy.Add(io.GlobalId, io as SynchronousMachine); break; case DMSType.ANALOGVALUE: io = new AnalogValue(globalId); analogPointsCopy.Add(io as AnalogValue); break; case DMSType.DISCRETEVALUE: io = new DiscreteValue(globalId); discretPointsCopy.Add(io as DiscreteValue); break; default: string message = String.Format("Failed to create entity because specified type ({0}) is not supported.", type); CommonTrace.WriteTrace(CommonTrace.TraceError, message); throw new Exception(message); } return(io); }
public List <SynchronousMachine> GetAllDERs() { int iteratorId = 0; List <long> ids = new List <long>(); List <SynchronousMachine> syncMachines = new List <SynchronousMachine>(); try { int numberOfResources = 500; int resourcesLeft = 0; List <ModelCode> properties = modelResourcesDesc.GetAllPropertyIds(ModelCode.SYNCMACHINE); iteratorId = GdaQueryProxy.GetExtentValues(ModelCode.SYNCMACHINE, properties); resourcesLeft = GdaQueryProxy.IteratorResourcesLeft(iteratorId); while (resourcesLeft > 0) { List <ResourceDescription> rds = GdaQueryProxy.IteratorNext(numberOfResources, iteratorId); for (int i = 0; i < rds.Count; i++) { var rg = GdaQueryProxy.GetValues(rds[i].Id, properties); SynchronousMachine syncMachine = new SynchronousMachine(rds[i].Id); syncMachines.Add(syncMachine.ConvertFromRD(rg)); } resourcesLeft = GdaQueryProxy.IteratorResourcesLeft(iteratorId); } GdaQueryProxy.IteratorClose(iteratorId); CommonTrace.WriteTrace(CommonTrace.TraceError, "Getting extent values method successfully finished."); } catch (Exception e) { string message = string.Format("Getting extent values method failed for {0}.\n\t{1}", ModelCode.SYNCMACHINE, e.Message); Console.WriteLine(message); CommonTrace.WriteTrace(CommonTrace.TraceError, message); } return(syncMachines); }
private List <SynchronousMachine> GetSynchronousMachineForSubstations(List <Substation> substations) { List <SynchronousMachine> resultIds = new List <SynchronousMachine>(); int numberOfResources = 500; Association association = new Association(ModelCode.EQCONTAINER_EQUIPMENTS, 0, false); try { List <ModelCode> properties = modelResourcesDesc.GetAllPropertyIds(ModelCode.SYNCMACHINE); foreach (Substation substation in substations) { int iteratorId = GdaQueryProxy.GetRelatedValues(substation.GlobalId, properties, association); int resourcesLeft = GdaQueryProxy.IteratorResourcesLeft(iteratorId); while (resourcesLeft > 0) { List <ResourceDescription> rds = GdaQueryProxy.IteratorNext(numberOfResources, iteratorId); foreach (ResourceDescription rd in rds) { SynchronousMachine synchronousMachine = new SynchronousMachine(rd.Id); resultIds.Add(synchronousMachine.ConvertFromRD(rd)); } resourcesLeft = GdaQueryProxy.IteratorResourcesLeft(iteratorId); } GdaQueryProxy.IteratorClose(iteratorId); } CommonTrace.WriteTrace(CommonTrace.TraceError, "Getting extent values method successfully finished."); } catch (Exception) { //string message = string.Format("Getting related values method failed for sourceGlobalId = {0} and association (propertyId = {1}, type = {2}). Reason: {3}", regionGid, association.PropertyId, association.Type, e.Message); //Console.WriteLine(message); //CommonTrace.WriteTrace(CommonTrace.TraceError, message); } return(resultIds); }
public List <SynchronousMachine> GetSyncMachinesForAreaGroupGid(long areaGid) { List <SynchronousMachine> resultIds = new List <SynchronousMachine>(); int numberOfResources = 500; Association association = new Association(ModelCode.AOR_GROUP_SYNCMACHINES, 0, false); try { List <ModelCode> properties = modelResourcesDesc.GetAllPropertyIds(ModelCode.SYNCMACHINE); int iteratorId = GdaQueryProxy.GetRelatedValues(areaGid, properties, association); int resourcesLeft = GdaQueryProxy.IteratorResourcesLeft(iteratorId); while (resourcesLeft > 0) { List <ResourceDescription> rds = GdaQueryProxy.IteratorNext(numberOfResources, iteratorId); foreach (ResourceDescription rd in rds) { SynchronousMachine tempSM = new SynchronousMachine(rd.Id); resultIds.Add(tempSM.ConvertFromRD(rd)); } resourcesLeft = GdaQueryProxy.IteratorResourcesLeft(iteratorId); } GdaQueryProxy.IteratorClose(iteratorId); CommonTrace.WriteTrace(CommonTrace.TraceError, "Getting extent values method (GetSyncMachinesForAreaGid) successfully finished."); } catch (Exception e) { string message = string.Format("Getting related values method failed for sourceGlobalId = {0} and association (propertyId = {1}, type = {2}). Reason: {3}", areaGid, association.PropertyId, association.Type, e.Message); Console.WriteLine(message); CommonTrace.WriteTrace(CommonTrace.TraceError, message); } return(resultIds); }
public SynchronousMachine GetSyncMachineByGid(long gid) { SynchronousMachine syncMachine = null; try { List <ModelCode> properties = modelResourcesDesc.GetAllPropertyIds(ModelCode.SYNCMACHINE); ResourceDescription rd = GdaQueryProxy.GetValues(gid, properties); syncMachine = new SynchronousMachine(rd.Id); syncMachine.ConvertFromRD(rd); CommonTrace.WriteTrace(CommonTrace.TraceError, "Getting extent values method successfully finished."); } catch (Exception e) { string message = string.Format("Getting extent values method failed for {0}.\n\t{1}", ModelCode.SYNCMACHINE, e.Message); Console.WriteLine(message); CommonTrace.WriteTrace(CommonTrace.TraceError, message); } return(syncMachine); }
private async Task <ITopologyElement> GetPopulatedElement(ResourceDescription rs) { string verboseMessage = $"{baseLogString} entering GetPopulatedElement method."; Logger.LogVerbose(verboseMessage); ITopologyElement topologyElement = new TopologyElement(rs.Id); try { DMSType type = GetDMSTypeOfTopologyElement(rs.Id); topologyElement.Mrid = rs.GetProperty(ModelCode.IDOBJ_MRID).AsString(); topologyElement.Name = rs.GetProperty(ModelCode.IDOBJ_NAME).AsString(); topologyElement.Description = rs.GetProperty(ModelCode.IDOBJ_DESCRIPTION).AsString(); topologyElement.DmsType = type.ToString(); if (rs.ContainsProperty(ModelCode.CONDUCTINGEQUIPMENT_ISREMOTE)) { topologyElement.IsRemote = rs.GetProperty(ModelCode.CONDUCTINGEQUIPMENT_ISREMOTE).AsBool(); } else { topologyElement.IsRemote = false; } if (rs.ContainsProperty(ModelCode.BREAKER_NORECLOSING)) { topologyElement.NoReclosing = rs.GetProperty(ModelCode.BREAKER_NORECLOSING).AsBool(); if (!topologyElement.NoReclosing) { topologyElement = new Recloser(topologyElement); } } else { topologyElement.NoReclosing = true; } if (rs.ContainsProperty(ModelCode.CONDUCTINGEQUIPMENT_BASEVOLTAGE)) { long baseVoltageGid = rs.GetProperty(ModelCode.CONDUCTINGEQUIPMENT_BASEVOLTAGE).AsLong(); var voltageResult = await BaseVoltages.TryGetValueAsync(baseVoltageGid); if (voltageResult.HasValue) { topologyElement.NominalVoltage = voltageResult.Value; } else if (baseVoltageGid == 0) { Logger.LogError($"{baseLogString} GetPopulatedElement => BaseVoltage with GID {baseVoltageGid:X16} does not exist in baseVoltages collection."); } } else { topologyElement.NominalVoltage = 0; } if (rs.ContainsProperty(ModelCode.BREAKER_NORECLOSING) && !rs.GetProperty(ModelCode.BREAKER_NORECLOSING).AsBool()) { var reclosersResult = await Reclosers.TryGetValueAsync(ReliableDictionaryNames.Reclosers); if (reclosersResult.HasValue) { var reclosers = reclosersResult.Value; reclosers.Add(topologyElement.Id); await Reclosers.SetAsync(ReliableDictionaryNames.Reclosers, reclosers); } else { Logger.LogWarning($"{baseLogString} Reliable collection '{ReliableDictionaryNames.Reclosers}' was not defined yet. Handling..."); await Reclosers.SetAsync(ReliableDictionaryNames.Reclosers, new HashSet <long>() { topologyElement.Id }); } } if (rs.ContainsProperty(ModelCode.ENERGYCONSUMER_TYPE)) { topologyElement = new EnergyConsumer(topologyElement) { Type = (EnergyConsumerType)rs.GetProperty(ModelCode.ENERGYCONSUMER_TYPE).AsEnum() }; } if (type == DMSType.SYNCHRONOUSMACHINE) { topologyElement = new SynchronousMachine(topologyElement); if (rs.ContainsProperty(ModelCode.SYNCHRONOUSMACHINE_CAPACITY)) { ((SynchronousMachine)topologyElement).Capacity = rs.GetProperty(ModelCode.SYNCHRONOUSMACHINE_CAPACITY).AsFloat(); } if (rs.ContainsProperty(ModelCode.SYNCHRONOUSMACHINE_CURRENTREGIME)) { ((SynchronousMachine)topologyElement).CurrentRegime = rs.GetProperty(ModelCode.SYNCHRONOUSMACHINE_CURRENTREGIME).AsFloat(); } } } catch (Exception e) { Logger.LogError($"{baseLogString} GetPopulatedElement => Could not get all properties." + $"{Environment.NewLine}Excepiton message: {e.Message}" + $"{Environment.NewLine} Stack trace: {e.StackTrace}"); } return(topologyElement); }
public void UpdateForecastDataDer(ForecastObject foDer) { AnalogValue analogActive = foDer.HourlyP.FirstOrDefault(); SynchronousMachine der = model.DersOriginal.Where(o => o.GlobalId.Equals(foDer.DerGID)).FirstOrDefault(); LogHelper.Log(LogTarget.File, LogService.CalculationEngineForecast, " INFO - CalculationEngineForecast.cs - Update forecast data for : " + der.GlobalId); if (analogActive != null) { long analogActiveGId = foDer.HourlyP.FirstOrDefault().GlobalId; //get Command list for analog values if (CalculationEngineModel.Instance.AppliedCommands.ContainsKey(analogActiveGId)) { List <Command> comActive = CalculationEngineModel.Instance.AppliedCommands[analogActiveGId]; if (comActive.Count > 0) { foreach (var activeAnalogForecastValue in foDer.HourlyP) { foreach (var activeAnalogCommandValue in comActive) { //ako je start komande zakacio vreme prognozirane vrednosti, moramo uzeti u obzir taj setpoint if ((activeAnalogForecastValue.Timestamp >= activeAnalogCommandValue.StartTime) && (activeAnalogForecastValue.Timestamp < activeAnalogCommandValue.EndTime)) { var newIncrease = activeAnalogForecastValue.Value + der.DERFlexibilityP; var newDecrease = activeAnalogForecastValue.Value - der.DERFlexibilityP; activeAnalogForecastValue.PowIncrease = newIncrease; activeAnalogForecastValue.PowDecrease = newDecrease; activeAnalogForecastValue.Value += activeAnalogCommandValue.DemandedPower; } } } } } } AnalogValue analogReactive = foDer.HourlyQ.FirstOrDefault(); if (analogReactive != null) { long analogReactiveGId = foDer.HourlyQ[0].GlobalId; //get Command list for analog values if (CalculationEngineModel.Instance.AppliedCommands.ContainsKey(analogReactiveGId)) { List <Command> comReactive = CalculationEngineModel.Instance.AppliedCommands[analogReactiveGId]; //if der is solar, HourlyQ list should be empty if (foDer.HourlyQ.Count == 0) { return; } if (comReactive.Count > 0) { foreach (var reactiveAnalogForecastValue in foDer.HourlyQ) { foreach (var reactiveAnalogCommandValue in comReactive) { //ako je start komande zakacio vreme prognozirane vrednosti, moramo uzeti u obzir taj setpoint if ((reactiveAnalogForecastValue.Timestamp >= reactiveAnalogCommandValue.StartTime) && (reactiveAnalogForecastValue.Timestamp < reactiveAnalogCommandValue.EndTime)) { var newIncreaseReactive = reactiveAnalogForecastValue.Value + der.DERFlexibilityQ; var newDecreaseReactive = reactiveAnalogForecastValue.Value - der.DERFlexibilityQ; reactiveAnalogForecastValue.PowIncrease = newIncreaseReactive; reactiveAnalogForecastValue.PowDecrease = newDecreaseReactive; reactiveAnalogForecastValue.Value += reactiveAnalogCommandValue.DemandedPower; } } } } } } }
/// <summary> /// Distribute required power by available reserve per each DER /// </summary> /// <param name="gid"> Region, subRegion or Entire network</param> /// <param name="demandedValue">Demanded power value</param> /// <param name="powerType"> Power type (Active/Reactive)</param> /// <param name="anaValues"> List of Analog Values</param> /// <returns></returns> public Setpoint AvailableReserveDistribution(long gid, float demandedValue, PowerType powerType, List <AnalogValue> anaValues) { LogHelper.Log(LogTarget.File, LogService.CalculationEngineDistributer, " INFO - CalculationEngineDistributer.cs - Distribute required power by available reserve per each DER for gid: " + gid); List <SynchronousMachine> syncMachines = RDAdapter.GetDERs(gid); // Get all DERs from a region, subregion or substation List <AnalogValue> analogValues = anaValues; SynchronousMachine syncMachine = null; Dictionary <long, float> PDistributionBySM = new Dictionary <long, float>(syncMachines.Count); //Dictionary<long, float> currentReserveBySm = new Dictionary<long, float>(syncMachines.Count); Setpoint setpoint = new Setpoint(); setpoint.PDistributionByAV = new Dictionary <long, float>(); float demandValue = demandedValue; float smFlexibility = 0; float smAvailableReserve = 0; float smAvailableReserveUp = 0; float smAvailableReserveDown = 0; float smAvailableReserveSum = 0; float smMaxPower = 0; float smMinPower = 0; float safetyCounter = 0; bool isDeltaPositive = false; isDeltaPositive = demandedValue >= 0; foreach (AnalogValue aValue in anaValues.Where(a => a.PowerType == powerType)) { syncMachine = syncMachines.Find(sm => sm.GlobalId == aValue.SynchronousMachine); switch (powerType) { case PowerType.Active: smAvailableReserveUp = syncMachine.MaxP - aValue.Value; smAvailableReserveDown = aValue.Value - syncMachine.MinP; break; case PowerType.Reactive: smAvailableReserveUp = syncMachine.MaxQ - aValue.Value; smAvailableReserveDown = aValue.Value - syncMachine.MinQ; break; default: throw new FormatException("Invalid power type assigned to AnalogValue."); } smAvailableReserve = isDeltaPositive ? smAvailableReserveUp : smAvailableReserveDown; smAvailableReserveSum += smAvailableReserve; } while (demandValue > 0 && isDeltaPositive == true || demandValue < 0 && isDeltaPositive == false) { foreach (AnalogValue aValue in anaValues.Where(a => a.PowerType == powerType)) { syncMachine = syncMachines.Find(sm => sm.GlobalId == aValue.SynchronousMachine); switch (powerType) { case PowerType.Active: smMaxPower = syncMachine.MaxP; smMinPower = syncMachine.MinP; smFlexibility = syncMachine.DERFlexibilityP; smAvailableReserveUp = syncMachine.MaxP - aValue.Value; smAvailableReserveDown = aValue.Value - syncMachine.MinP; break; case PowerType.Reactive: smMaxPower = syncMachine.MaxQ; smMinPower = syncMachine.MinQ; smFlexibility = syncMachine.DERFlexibilityQ; smAvailableReserveUp = syncMachine.MaxQ - aValue.Value; smAvailableReserveDown = aValue.Value - syncMachine.MinQ; break; default: break; } if (aValue.Value == smMaxPower && isDeltaPositive == true) { continue; } if (aValue.Value == smMinPower && isDeltaPositive == false) { continue; } long referencedSMgid = aValue.SynchronousMachine; smAvailableReserve = isDeltaPositive ? smAvailableReserveUp : smAvailableReserveDown; if (smAvailableReserve == 0) { continue; } float k = smAvailableReserve * demandedValue / smAvailableReserveSum; //korak redukovanja K, ne moze biti veci od MAX ni manji od MIN ReduceKToProperValue(ref k, smAvailableReserve, isDeltaPositive, aValue); if (Math.Abs(k) <= smFlexibility) { CheckDistributedPartsOnGoodFlex(PDistributionBySM, aValue, setpoint, k, smFlexibility, isDeltaPositive, ref demandValue); } else { CheckDistributedPartsOnPoorFlex(PDistributionBySM, aValue, setpoint, k, smFlexibility, isDeltaPositive, ref demandValue); } } if (safetyCounter++ == 5) { Trace.Write("Warning: 5 iterations were done, but no solution has been found."); return(setpoint); } } return(setpoint); }
public void GetAnalogScadaData(List <AnalogValue> values) { if (values != null) { Console.WriteLine("\n****"); List <object> measurements = new List <object>(); foreach (AnalogValue item in values) { // Koliko komanda uvecava vrednost float commandValue = 0; // Lista komandi za analogni signal List <Command> commands = new List <Command>(); // Pribavljanje liste model.AppliedCommands.TryGetValue(item.GlobalId, out commands); // DER SynchronousMachine sm = model.DersOriginal.Where(o => o.GlobalId.Equals(item.SynchronousMachine)).FirstOrDefault(); if (sm == null) { LogHelper.Log(LogTarget.File, LogService.CEDataCollector, " WARNING - SCADADataCollector.cs - Synchronous machine with " + item.SynchronousMachine + " global id does not exist."); continue; } if (commands != null) { Command command = commands.Where(o => o.StartTime <= DateTime.Now.Ticks && o.EndTime > DateTime.Now.Ticks).FirstOrDefault(); if (command != null) { commandValue = command.DemandedPower; } } if (item.PowerType == FTN.Common.PowerType.Active) { item.PowIncrease = item.Value + sm.DERFlexibilityP - commandValue; item.PowDecrease = item.Value - sm.DERFlexibilityP - commandValue; if (item.PowIncrease > sm.MaxP) { item.PowIncrease = sm.MaxP; } if (item.PowDecrease < sm.MinP) { item.PowDecrease = sm.MinP; } } else { item.PowIncrease = item.Value + sm.DERFlexibilityQ - commandValue; item.PowDecrease = item.Value - sm.DERFlexibilityQ - commandValue; if (item.PowIncrease > sm.MaxQ) { item.PowIncrease = sm.MaxQ; } if (item.PowDecrease < sm.MinQ) { item.PowDecrease = sm.MinQ; } //item.Value += commandValue; } measurements.Add(item); } //Sent to TSDB proxyTSDB.Proxy.WriteAnalogValue(values); //when data from SCADA is received, publish it to all clients SmartCache.Instance.Cache.CacheList.Clear(); SmartCache.Instance.Cache.CacheList.Add(new CacheObject(DateTime.Now, measurements)); SmartCache.Instance.ReceiveCache("", null); } }
/// <summary> /// Distributes demanded power to DERs associated to specific gid. /// </summary> /// <param name="gid">Region, subregion, or entire network </param> /// <param name="demandedValue">Demanded Value</param> /// <param name="powerType"> Power Type (Active/Reactive) </param> /// <param name="anaValues"> List of analog values </param> /// <returns></returns> public Setpoint NominalPowerDistribution(long gid, float demandedValue, PowerType powerType, List <AnalogValue> anaValues) { LogHelper.Log(LogTarget.File, LogService.CalculationEngineDistributer, " INFO - CalculationEngineDistributer.cs - Distribute demanded power to DERs associated to gid: " + gid); List <SynchronousMachine> syncMachines = RDAdapter.GetDERs(gid); // Get all DERs from a region, subregion or substation List <AnalogValue> analogValues = anaValues; Dictionary <long, float> PDistributionBySM = new Dictionary <long, float>(syncMachines.Count); SynchronousMachine syncMachine = null; Setpoint setpoint = new Setpoint(); setpoint.PDistributionByAV = new Dictionary <long, float>(syncMachines.Count); long smGid = 0; int safetyCounter = 0; float coefficient = 0; float smNominalPower = 0; float nominalPowerSum = 0; float smDelta = 0; float smFlexibility = 0; float smMaxPower = 0; float smMinPower = 0; float smAvailableReserve = 0; float smAvailableReserveUp = 0; float smAvailableReserveDown = 0; float demandValue = demandedValue; bool isDeltaPositive = false; isDeltaPositive = demandedValue >= 0; switch (powerType) { case PowerType.Active: nominalPowerSum = syncMachines.Sum(o => o.NominalP); break; case PowerType.Reactive: nominalPowerSum = syncMachines.Sum(o => o.NominalQ); break; default: break; } coefficient = demandedValue / nominalPowerSum; while (demandValue > 0 && isDeltaPositive == true || demandValue < 0 && isDeltaPositive == false) { foreach (AnalogValue aValue in analogValues.Where(p => p.PowerType == powerType)) { syncMachine = syncMachines.Find(sm => sm.GlobalId == aValue.SynchronousMachine); switch (powerType) { case PowerType.Active: smFlexibility = syncMachine.DERFlexibilityP; smMaxPower = syncMachine.MaxP; smMinPower = syncMachine.MinP; smNominalPower = syncMachine.NominalP; smAvailableReserveUp = syncMachine.MaxP - aValue.Value; smAvailableReserveDown = aValue.Value - syncMachine.MinP; break; case PowerType.Reactive: smFlexibility = syncMachine.DERFlexibilityQ; smMaxPower = syncMachine.MaxQ; smMinPower = syncMachine.MinQ; smNominalPower = syncMachine.NominalQ; smAvailableReserveUp = syncMachine.MaxQ - aValue.Value; smAvailableReserveDown = aValue.Value - syncMachine.MinQ; break; default: break; } if (aValue.Value == smMaxPower && isDeltaPositive == true) { continue; } if (aValue.Value == smMinPower && isDeltaPositive == false) { continue; } smDelta = coefficient * smNominalPower; // Proportionaly split required power, by nominalP value smGid = syncMachine.GlobalId; smAvailableReserve = isDeltaPositive ? smAvailableReserveUp : smAvailableReserveDown; if (smAvailableReserve == 0) { LogHelper.Log(LogTarget.File, LogService.CalculationEngineDistributer, " WARNING - CalculationEngineDistributer.cs - No available reserve for gid: " + gid); continue; } //korak redukovanja K, ne moze biti veci od MAX ni manji od MIN ReduceKToProperValue(ref smDelta, smAvailableReserve, isDeltaPositive, aValue); if (Math.Abs(smDelta) <= smFlexibility) // ako delta ne prelazi max, da li je DER dovoljno flexibilan? { CheckDistributedPartsOnGoodFlex(PDistributionBySM, aValue, setpoint, smDelta, smFlexibility, isDeltaPositive, ref demandValue); } else // ako DER nije dovoljno fleksibilan { CheckDistributedPartsOnPoorFlex(PDistributionBySM, aValue, setpoint, smDelta, smFlexibility, isDeltaPositive, ref demandValue); } } if (safetyCounter++ == 5) { Trace.Write("Warning: 5 iterations were done, but no solution has been found."); LogHelper.Log(LogTarget.File, LogService.CalculationEngineDistributer, " WARNING - CalculationEngineDistributer.cs - 5 iterations were done, but no solution has been found to gid: " + gid); return(setpoint); } } return(setpoint); }
/// <summary> /// Simulation of analog points changes /// </summary> private void SimulatorForAnalogPoints() { while (true) { lock (SimulatorModel.Instance.Lock2PC) { foreach (AnalogValue value in model.AnalogPoints) { SynchronousMachine der = model.Ders[value.SynchronousMachine]; if (!SimulatorModel.Instance.CurrentWeathers.ContainsKey(der.GlobalId)) { Console.WriteLine(DateTime.Now + ": Weather forecast is not available for GlobalId: " + der.GlobalId); continue; } CAS signal = SimulatorModel.Instance.ControlActiveSignals.Where(o => o.Gid.Equals(value.GlobalId)).FirstOrDefault(); if (signal != null) { if (signal.ControlledBy.Equals(CASEnum.Normal)) { Console.WriteLine(DateTime.Now + ": Signal gid: {0}, Status: {1}", signal.Gid, signal.ControlledBy); continue; } } WeatherInfo wInfo = SimulatorModel.Instance.CurrentWeathers[der.GlobalId]; switch (der.FuelType) { case FuelType.Sun: { if (value.PowerType == PowerType.Reactive) { float currentQ = 0; currentQ = RawValuesConverter.ConvertRange(currentQ, EGU_MIN, EGU_MAX, RAW_MIN, RAW_MAX); WriteSingleHoldingRegister(value.Address, currentQ); } else { long sunriseTime = wInfo.Daily.Data.FirstOrDefault().SunriseTime; long sunsetTime = wInfo.Daily.Data.FirstOrDefault().SunsetTime; float currentP = pCalculator.GetActivePowerForSolarGenerator((float)wInfo.Currently.Temperature, (float)wInfo.Currently.CloudCover, der.NominalP, sunriseTime, sunsetTime); currentP = RawValuesConverter.ConvertRange(currentP, EGU_MIN, EGU_MAX, RAW_MIN, RAW_MAX); WriteSingleHoldingRegister(value.Address, currentP); } } break; case FuelType.Wind: { float currentP = pCalculator.GetActivePowerForWindGenerator(der.NominalP, (float)(wInfo.Currently.WindSpeed)); if (value.PowerType == PowerType.Reactive) { // 5% of active power float currentQ = currentP * 0.05f; currentQ = RawValuesConverter.ConvertRange(currentQ, EGU_MIN, EGU_MAX, RAW_MIN, RAW_MAX); WriteSingleHoldingRegister(value.Address, currentQ); } else { currentP = RawValuesConverter.ConvertRange(currentP, EGU_MIN, EGU_MAX, RAW_MIN, RAW_MAX); WriteSingleHoldingRegister(value.Address, currentP); } } break; } } } Thread.Sleep(5000); } }
public Dictionary <Type, Dictionary <string, IdentifiedObject> > CreateObjectModel(Dictionary <string, DataVertex> globalVertices, Dictionary <string, List <DataEdge> > globalEdges, Dictionary <string, CableConfiguration> globalCableConfiguration, Dictionary <string, SpotLoad> globalSpotLoads) { globalComponentDictionary = new Dictionary <Type, Dictionary <string, IdentifiedObject> >(); terminalPairsContainer = new List <TerminalPair>(); perLengthImpedanceContainer = new Dictionary <string, PerLengthImpedance>(); wireInfoContainer = new Dictionary <string, WireInfo>(); usagePointContainer = new Dictionary <string, SpotLoad>(); powerTransformerEnding = new Dictionary <string, DataVertexTransformer>(); PSRType local_psr_pt = new PSRType(); circuit = new Circuit(); string mrid = Guid.NewGuid().ToString(); PSRType psrTypeCircuit = new PSRType() { MRID = "Feeder", Name = "Feeder" }; circuit.PSRType = psrTypeCircuit; circuit.ID = mrid; circuit.MRID = mrid; circuit.Name = "Feeder_36"; addComponentToGlobalDictionary(circuit, circuit.GetType()); addComponentToGlobalDictionary(psrTypeCircuit, psrTypeCircuit.GetType()); Dictionary <string, ConnectivityNode> connectivityNodeContainer = new Dictionary <string, ConnectivityNode>(); foreach (DataVertex dataVertex in globalVertices.Values) { if (dataVertex.typeOfVertex == DataVertex.TypeOfVertex.TRANSFORMER_VERTEX) { PowerTransformer powerTransformer = new PowerTransformer(); DataVertexTransformer dvt = (DataVertexTransformer)dataVertex; string power_transformer_mrid = Guid.NewGuid().ToString(); powerTransformer.ID = power_transformer_mrid; powerTransformer.MRID = power_transformer_mrid; powerTransformer.Name = "2 winding power transformer"; local_psr_pt = new PSRType() { Name = "Consumer Transformer", MRID = "Consumer Transformer" }; powerTransformer.PSRType = local_psr_pt; powerTransformer.EquipmentContainer = circuit; addComponentToGlobalDictionary(local_psr_pt, local_psr_pt.GetType()); ConnectivityNode w1T_cn = new ConnectivityNode(); string connectivity_node_mrid = Guid.NewGuid().ToString(); w1T_cn.ID = connectivity_node_mrid; w1T_cn.MRID = connectivity_node_mrid; w1T_cn.ConnectivityNodeContainer = circuit; if ((dataVertex as DataVertexTransformer).Line_from == null) { continue; } ; w1T_cn.Name = (dataVertex as DataVertexTransformer).Line_from; connectivityNodeContainer.Add((dataVertex as DataVertexTransformer).Line_from, w1T_cn); addComponentToGlobalDictionary(w1T_cn, w1T_cn.GetType()); ConnectivityNode w2T_cn = new ConnectivityNode(); connectivity_node_mrid = Guid.NewGuid().ToString(); w2T_cn.ID = connectivity_node_mrid; w2T_cn.MRID = connectivity_node_mrid; w2T_cn.ConnectivityNodeContainer = circuit; w2T_cn.Name = (dataVertex as DataVertexTransformer).Line_to; connectivityNodeContainer.Add((dataVertex as DataVertexTransformer).Line_to, w2T_cn); if ((dataVertex as DataVertexTransformer).Line_to == null) { continue; } ; addComponentToGlobalDictionary(w2T_cn, w2T_cn.GetType()); Terminal w1T = new Terminal(); w1T.MRID = power_transformer_mrid + ".W1.T"; w1T.ID = power_transformer_mrid + ".W1.T"; w1T.SequenceNumber = 1; w1T.ConductingEquipment = powerTransformer; w1T.ConnectivityNode = w1T_cn; w1T.Phases = PhaseCode.s2N; w1T.Name = "Transformer end terminal 1"; Terminal w2T = new Terminal(); w2T.MRID = power_transformer_mrid + ".W2.T"; w2T.ID = power_transformer_mrid + ".W2.T"; w2T.SequenceNumber = 2; w2T.ConductingEquipment = powerTransformer; w2T.ConnectivityNode = w2T_cn; w2T.Phases = PhaseCode.s2N; w2T.Name = "Transformer end terminal 2"; terminalPairsContainer.Add(new TerminalPair() { terminalA = w1T, terminalB = w2T }); addComponentToGlobalDictionary(w1T, w1T.GetType()); addComponentToGlobalDictionary(w2T, w2T.GetType()); PowerTransformerEnd powerTransformerEnd1 = new PowerTransformerEnd(); powerTransformerEnd1.ID = power_transformer_mrid + ".W1"; powerTransformerEnd1.MRID = power_transformer_mrid + ".W1"; powerTransformerEnd1.Name = dvt.NameA; powerTransformerEnd1.Terminal = w1T; powerTransformerEnd1.Grounded = false; powerTransformerEnd1.EndNumber = 1; powerTransformerEnd1.PowerTransformer = powerTransformer; powerTransformerEnd1.ConnectionKind = WindingConnection.D; powerTransformerEnd1.PhaseAngleClock = 0; powerTransformerEnd1.RatedS = (float)dvt._kVA_A; powerTransformerEnd1.RatedU = (float)dvt._kV_LowA; PowerTransformerEnd powerTransformerEnd2 = new PowerTransformerEnd(); powerTransformerEnd2.ID = power_transformer_mrid + ".W2"; powerTransformerEnd2.MRID = power_transformer_mrid + ".W2"; powerTransformerEnd2.Name = dvt.NameB; powerTransformerEnd2.Terminal = w2T; powerTransformerEnd2.Grounded = false; powerTransformerEnd2.EndNumber = 1; powerTransformerEnd2.PowerTransformer = powerTransformer; powerTransformerEnd2.ConnectionKind = WindingConnection.D; powerTransformerEnd2.PhaseAngleClock = 0; powerTransformerEnd2.RatedS = (float)dvt._kVA_B; powerTransformerEnd2.RatedU = (float)dvt._kV_LowB; addComponentToGlobalDictionary(powerTransformer, powerTransformer.GetType()); addComponentToGlobalDictionary(powerTransformerEnd1, powerTransformerEnd1.GetType()); addComponentToGlobalDictionary(powerTransformerEnd2, powerTransformerEnd2.GetType()); } if (dataVertex.typeOfVertex == DataVertex.TypeOfVertex.REGULATOR_VERTEX) { string sync_machine = Guid.NewGuid().ToString(); PSRType psr_sync_machine = new PSRType() { MRID = "Generator", Name = "Generator" }; SynchronousMachine sm = new SynchronousMachine() { Name = dataVertex.Text, MRID = sync_machine, ID = sync_machine, EquipmentContainer = circuit }; addComponentToGlobalDictionary(sm, sm.GetType()); addComponentToGlobalDictionary(psr_sync_machine, psr_sync_machine.GetType()); } } foreach (List <DataEdge> dataEdgeCollection in globalEdges.Values) { foreach (DataEdge dataEdge in dataEdgeCollection) { string acLineSegment_mrid = Guid.NewGuid().ToString(); ConnectivityNode T1_cn = new ConnectivityNode(); string connectivity_node_mrid = Guid.NewGuid().ToString(); T1_cn.ID = connectivity_node_mrid; T1_cn.MRID = connectivity_node_mrid; T1_cn.ConnectivityNodeContainer = circuit; T1_cn.Name = (dataEdge.Source as DataVertex).Element_id; if (connectivityNodeContainer.ContainsKey((dataEdge.Source as DataVertex).Element_id) == false) { connectivityNodeContainer.Add(dataEdge.Source.Element_id, T1_cn); addComponentToGlobalDictionary(T1_cn, T1_cn.GetType()); } ConnectivityNode T2_cn = new ConnectivityNode(); connectivity_node_mrid = Guid.NewGuid().ToString(); T2_cn.ID = connectivity_node_mrid; T2_cn.MRID = connectivity_node_mrid; T2_cn.ConnectivityNodeContainer = circuit; T2_cn.Name = (dataEdge.Target as DataVertex).Element_id; if (connectivityNodeContainer.ContainsKey((dataEdge.Target as DataVertex).Element_id) == false) { connectivityNodeContainer.Add(dataEdge.Target.Element_id, T2_cn); addComponentToGlobalDictionary(T2_cn, T2_cn.GetType()); } Terminal T1 = new Terminal(); //string terminal_mrid = Guid.NewGuid().ToString(); T1.ID = acLineSegment_mrid + ".T1"; T1.MRID = acLineSegment_mrid + ".T1"; T1.Name = dataEdge.Source.Element_id; T1.Phases = PhaseCode.ABC; ACDCTerminal acdc_terminal = new ACDCTerminal() { SequenceNumber = 1 }; T1.SequenceNumber = acdc_terminal.SequenceNumber; T1.ConnectivityNode = T1_cn; Terminal T2 = new Terminal(); T2.ID = acLineSegment_mrid + ".T2"; T2.MRID = acLineSegment_mrid + ".T2"; T2.Name = dataEdge.Target.Element_id; T2.Phases = PhaseCode.ABC; ACDCTerminal acdc_terminal2 = new ACDCTerminal() { SequenceNumber = 2 }; T2.SequenceNumber = acdc_terminal2.SequenceNumber; T2.ConnectivityNode = T2_cn; string perLengthImpedance_mrid = Guid.NewGuid().ToString(); PerLengthImpedance pli = createPerLengthImpedanceObject(dataEdge.Configuration, perLengthImpedance_mrid); AssetInfo wi = createWireInfoObject(dataEdge.Configuration, perLengthImpedance_mrid); PSRType acPSRType = new PSRType() { MRID = "Section", Name = "Section" }; if (!globalComponentDictionary[acPSRType.GetType()].ContainsKey(acPSRType.Name)) { addComponentToGlobalDictionary(acPSRType, acPSRType.GetType()); } ACLineSegment acLineSegment = new ACLineSegment() { ID = acLineSegment_mrid, MRID = acLineSegment_mrid, Name = T1.Name.Split(' ').Last() + "-" + T2.Name.Split(' ').Last(), PSRType = acPSRType, EquipmentContainer = circuit, Length = (float)feetsToMeters(dataEdge.Length), PerLengthImpedance = pli, AssetDatasheet = wi }; addComponentToGlobalDictionary(acLineSegment, acLineSegment.GetType()); TerminalPair terminalPair = new TerminalPair() { terminalA = T1, terminalB = T2 }; terminalPairsContainer.Add(terminalPair); addComponentToGlobalDictionary(T1, T1.GetType()); addComponentToGlobalDictionary(T2, T2.GetType()); } } UsagePoint usagePoint = new UsagePoint(); foreach (DataVertex dv in globalVertices.Values) { if (dv.typeOfVertex == DataVertex.TypeOfVertex.SPOT_LOAD_VERTEX) { SpotLoad sl = (SpotLoad)dv; usagePoint = CreateSpotLoad(sl); addComponentToGlobalDictionary(usagePoint, usagePoint.GetType()); } } return(globalComponentDictionary); }
private void addComponentToGlobalDictionary(IdentifiedObject component, Type type) { if (!globalComponentDictionary.ContainsKey(type)) { globalComponentDictionary.Add(type, new Dictionary <string, IdentifiedObject>()); } if (type.Equals(typeof(ACLineSegment))) { ACLineSegment acl = (ACLineSegment)component; globalComponentDictionary[type].Add(acl.MRID, acl); } else if (type.Equals(typeof(Terminal))) { Terminal tp = (Terminal)component; globalComponentDictionary[tp.GetType()].Add(tp.MRID, tp); } else if (type.Equals(typeof(Circuit))) { Circuit cr = (Circuit)component; globalComponentDictionary[cr.GetType()].Add(cr.MRID, cr); } else if (type.Equals(typeof(WireInfo))) { WireInfo wi = (WireInfo)component; globalComponentDictionary[wi.GetType()].Add(wi.MRID, wi); } else if (type.Equals(typeof(PerLengthSequenceImpedance))) { PerLengthSequenceImpedance pli = (PerLengthSequenceImpedance)component; globalComponentDictionary[pli.GetType()].Add(pli.MRID, pli); } else if (type.Equals(typeof(ConnectivityNode))) { ConnectivityNode cn = (ConnectivityNode)component; globalComponentDictionary[cn.GetType()].Add(cn.MRID, cn); } else if (type.Equals(typeof(PowerTransformer))) { PowerTransformer pt = (PowerTransformer)component; globalComponentDictionary[pt.GetType()].Add(pt.MRID, pt); } else if (type.Equals(typeof(PowerTransformerEnd))) { PowerTransformerEnd pt = (PowerTransformerEnd)component; globalComponentDictionary[pt.GetType()].Add(pt.MRID, pt); } else if (type.Equals(typeof(UsagePoint))) { UsagePoint us = (UsagePoint)component; globalComponentDictionary[us.GetType()].Add(us.MRID, us); } else if (type.Equals(typeof(PSRType))) { PSRType psr = (PSRType)component; globalComponentDictionary[psr.GetType()].Add(psr.Name, psr); } else if (type.Equals(typeof(SynchronousMachine))) { SynchronousMachine sm = (SynchronousMachine)component; globalComponentDictionary[sm.GetType()].Add(sm.Name, sm); } }
private ITopologyElement GetPopulatedElement(ResourceDescription rs) { string errorMessage = $"[NMSManager] Failed to populate element with GID 0x{rs.Id:X16}. "; ITopologyElement topologyElement = new TopologyElement(rs.Id); try { DMSType type = GetDMSTypeOfTopologyElement(rs.Id); topologyElement.Mrid = rs.GetProperty(ModelCode.IDOBJ_MRID).AsString(); topologyElement.Name = rs.GetProperty(ModelCode.IDOBJ_NAME).AsString(); topologyElement.Description = rs.GetProperty(ModelCode.IDOBJ_DESCRIPTION).AsString(); topologyElement.DmsType = type.ToString(); if (rs.ContainsProperty(ModelCode.CONDUCTINGEQUIPMENT_ISREMOTE)) { topologyElement.IsRemote = rs.GetProperty(ModelCode.CONDUCTINGEQUIPMENT_ISREMOTE).AsBool(); } else { topologyElement.IsRemote = false; } if (rs.ContainsProperty(ModelCode.BREAKER_NORECLOSING)) { topologyElement.NoReclosing = rs.GetProperty(ModelCode.BREAKER_NORECLOSING).AsBool(); if (!topologyElement.NoReclosing) { topologyElement = new Recloser(topologyElement); } } else { topologyElement.NoReclosing = true; } if (rs.ContainsProperty(ModelCode.CONDUCTINGEQUIPMENT_BASEVOLTAGE)) { long baseVoltageGid = rs.GetProperty(ModelCode.CONDUCTINGEQUIPMENT_BASEVOLTAGE).AsLong(); if (BaseVoltages.TryGetValue(baseVoltageGid, out float voltage)) { topologyElement.NominalVoltage = voltage; } else if (baseVoltageGid == 0) { logger.LogError($"{errorMessage} BaseVoltage with GID 0x{baseVoltageGid.ToString("X16")} does not exist in baseVoltages collection."); } } else { topologyElement.NominalVoltage = 0; } if (rs.ContainsProperty(ModelCode.BREAKER_NORECLOSING) && !rs.GetProperty(ModelCode.BREAKER_NORECLOSING).AsBool()) { Reclosers.Add(topologyElement.Id); } if (rs.ContainsProperty(ModelCode.ENERGYCONSUMER_TYPE)) { topologyElement = new EnergyConsumer(topologyElement) { Type = (EnergyConsumerType)rs.GetProperty(ModelCode.ENERGYCONSUMER_TYPE).AsEnum() }; } if (type == DMSType.SYNCHRONOUSMACHINE) { topologyElement = new SynchronousMachine(topologyElement); if (rs.ContainsProperty(ModelCode.SYNCHRONOUSMACHINE_CAPACITY)) { ((SynchronousMachine)topologyElement).Capacity = rs.GetProperty(ModelCode.SYNCHRONOUSMACHINE_CAPACITY).AsFloat(); } if (rs.ContainsProperty(ModelCode.SYNCHRONOUSMACHINE_CURRENTREGIME)) { ((SynchronousMachine)topologyElement).CurrentRegime = rs.GetProperty(ModelCode.SYNCHRONOUSMACHINE_CURRENTREGIME).AsFloat(); } } } catch (Exception ex) { logger.LogError($"{errorMessage} Could not get all properties.Excepiton message: {ex.Message}"); } return(topologyElement); }
/// <summary> /// Creates entity for specified global inside the container. /// </summary> /// <param name="globalId">Global id of the entity for insert</param> /// <returns>Created entity (identified object).</returns> public IdentifiedObject CreateEntity(long globalId) { short type = ModelCodeHelper.ExtractTypeFromGlobalId(globalId); IdentifiedObject io = null; switch ((DMSType)type) { case DMSType.BASEVOLTAGE: { io = new BaseVoltage(globalId); break; } case DMSType.TERMINAL: { io = new Terminal(globalId); break; } case DMSType.CONNECTIVITYNODE: { io = new ConnectivityNode(globalId); break; } case DMSType.POWERTRANSFORMER: { io = new PowerTransformer(globalId); break; } case DMSType.ENERGYSOURCE: { io = new EnergySource(globalId); break; } case DMSType.ENERGYCONSUMER: { io = new EnergyConsumer(globalId); break; } case DMSType.TRANSFORMERWINDING: { io = new TransformerWinding(globalId); break; } case DMSType.FUSE: { io = new Fuse(globalId); break; } case DMSType.DISCONNECTOR: { io = new Disconnector(globalId); break; } case DMSType.BREAKER: { io = new Breaker(globalId); break; } case DMSType.LOADBREAKSWITCH: { io = new LoadBreakSwitch(globalId); break; } case DMSType.ACLINESEGMENT: { io = new ACLineSegment(globalId); break; } case DMSType.DISCRETE: { io = new Discrete(globalId); break; } case DMSType.ANALOG: { io = new Analog(globalId); break; } case DMSType.SYNCHRONOUSMACHINE: { io = new SynchronousMachine(globalId); break; } default: { string message = String.Format("Failed to create entity because specified type ({0}) is not supported.", type); Logger.LogError(message); throw new Exception(message); } } // Add entity to map this.AddEntity(io); return(io); }
public WeatherInfo Get7DayPerHourForecastByGid(long gid) { // Povratna vrednost WeatherInfo weatherInfoRetVal = new WeatherInfo(); // Lista substationa za koje se dobija vremenska prognoza List <Substation> substations = new List <Substation>(); // Pomocna lista List <WeatherInfo> temp = new List <WeatherInfo>(); // Iz gid-a se dobija DMSType i na osnovu toga se dalje pribavljaju substation-i DMSType type = (DMSType)ModelCodeHelper.ExtractTypeFromGlobalId(gid); switch (type) { case DMSType.REGION: // Ukoliko je gid od regiona, moraju se dobaviti svi sub region-i zatim od njih svi substation-i List <SubGeographicalRegion> subRegions = RdAdapter.GetSubRegionsForRegion(gid); // Prolazi se kroz sve subRegion-e i dobavljaju se svi substation-i foreach (SubGeographicalRegion subRegion in subRegions) { substations.AddRange(RdAdapter.GetSubstationsForSubRegion(subRegion.GlobalId)); } // Prolazi se kroz substation-e i za svaki se trazi predvidjanje vremenske prognoze foreach (Substation substation in substations) { lock (lockFW) { WeatherInfo info = null; forecastWeather.TryGetValue(substation.GlobalId, out info); if (info == null) { info = Get7DayPerHourForecastByLatLon(substation.Latitude, substation.Longitude); forecastWeather.Add(substation.GlobalId, info); } temp.Add(info); } } // Prolazi se 168 puta i za svaki substation za svaki sat se radi proracun prosecne prognoze for (int i = 0; i < temp.FirstOrDefault().Hourly.Data.Count; i++) { List <Data> section = new List <Data>(); foreach (WeatherInfo weatherInfo in temp) { section.Add(weatherInfo.Hourly.Data[i]); } weatherInfoRetVal.Hourly.Data.Add(CalculateAverageData(section)); } break; case DMSType.SUBREGION: // Ukoliko se radi o subregion-u, tada se za taj subregion dobavljaju svi substation-i substations.AddRange(RdAdapter.GetSubstationsForSubRegion(gid)); // Prolazi se kroz substation-e i za svaki se trazi vremenska prognoza foreach (Substation substation in substations) { lock (lockFW) { WeatherInfo info = null; forecastWeather.TryGetValue(substation.GlobalId, out info); if (info == null) { info = Get7DayPerHourForecastByLatLon(substation.Latitude, substation.Longitude); forecastWeather.Add(substation.GlobalId, info); } temp.Add(info); } } // Prolazi se 168 puta i za svaki substation za svaki sat se radi proracun prosecne prognoze for (int i = 0; i < temp.FirstOrDefault().Hourly.Data.Count; i++) { List <Data> section = new List <Data>(); foreach (WeatherInfo weatherInfo in temp) { section.Add(weatherInfo.Hourly.Data[i]); } weatherInfoRetVal.Hourly.Data.Add(CalculateAverageData(section)); } break; case DMSType.SUBSTATION: // Ukoliko se radi o substation-u, dobavi se odredjeni substation i za njega se trazi vremenska prognoza Substation tempSubstation = RdAdapter.GetSubstation(gid); //weatherInfoRetVal = Get7DayPerHourForecastByLatLon(tempSubstation.Latitude, tempSubstation.Longitude); lock (lockFW) { weatherInfoRetVal = null; forecastWeather.TryGetValue(tempSubstation.GlobalId, out weatherInfoRetVal); if (weatherInfoRetVal == null) { weatherInfoRetVal = Get7DayPerHourForecastByLatLon(tempSubstation.Latitude, tempSubstation.Longitude); forecastWeather.Add(tempSubstation.GlobalId, weatherInfoRetVal); } } break; case DMSType.SYNCMACHINE: // Ukoliko se radi o sinhronom masini, dobavim tu sinhronu masinu, i vidim u kom substationu se nalazi, // zatim zatrazim vremensku prognozu za taj substation SynchronousMachine sm = rdAdapter.GetSyncMachineByGid(gid); lock (lockFW) { weatherInfoRetVal = null; forecastWeather.TryGetValue(sm.EquipmentContainer, out weatherInfoRetVal); if (weatherInfoRetVal == null) { tempSubstation = RdAdapter.GetSubstation(sm.EquipmentContainer); weatherInfoRetVal = Get7DayPerHourForecastByLatLon(tempSubstation.Latitude, tempSubstation.Longitude); forecastWeather.Add(tempSubstation.GlobalId, weatherInfoRetVal); } } break; } return(weatherInfoRetVal); }
public ForecastObject CalculateHourlyForecastForDer(List <Data> hourlyDerData, SynchronousMachine der, long sunriseTime, long sunsetTime, AnalogValue modelDataActive, AnalogValue modelDataReactive) { ForecastObject forecastObj = new ForecastObject(); forecastObj.DerGID = der.GlobalId; //LogHelper.Log(LogTarget.File, LogService.CalculateHourlyForecast, " INFO - CalculateHourlyForecast.cs - Calculate hourly forecast for one der."); if (modelDataActive == null) { //LogHelper.Log(LogTarget.File, LogService.CalculateHourlyForecast, " ERROR - CalculateHourlyForecast.cs - Model data active object is null."); return(null); } foreach (Data derHour in hourlyDerData) { switch (der.FuelType) { case FuelType.Sun: { //get ders substation so you can get latitude and longitude //need this to calculate sunrise and sunset time for calculation of active power for solar float activePowSolar = powCalc.GetActivePowerForSolarGenerator((float)derHour.Temperature, (float)derHour.CloudCover, der.NominalP, sunriseTime, sunsetTime); float powIncrease = 0; float powDecrease = 0; float powIncreaseTemp = activePowSolar + der.DERFlexibilityP; float powDecreaseTemp = activePowSolar - der.DERFlexibilityP; if (powIncreaseTemp >= der.MaxP) { //LogHelper.Log(LogTarget.File, LogService.CalculateHourlyForecast, " WARNING - CalculateHourlyForecast.cs - Solar panel: "+der.GlobalId+" active power increase value change is higher or equal to max active power. New active power increase value is set to max active power value."); powIncrease = der.MaxP; } else { //LogHelper.Log(LogTarget.File, LogService.CalculateHourlyForecast, " INFO - CalculateHourlyForecast.cs - Solar panel: " + der.GlobalId + " active power increase value change is lower then max active power. New active power increase value is set regularly."); powIncrease = powIncreaseTemp; } if (powDecreaseTemp <= der.MinP) { //LogHelper.Log(LogTarget.File, LogService.CalculateHourlyForecast, " WARNING - CalculateHourlyForecast.cs - Solar panel: " + der.GlobalId + " active power decrease value change is lower or equal to min active power. New active power decrease value is set to min active power value."); powDecrease = der.MinP; } else { //LogHelper.Log(LogTarget.File, LogService.CalculateHourlyForecast, " INFO - CalculateHourlyForecast.cs - Solar panel: " + der.GlobalId + " active power decrease value change is higher then min active power. New active power decrease value is set regularly."); powDecrease = powDecreaseTemp; } forecastObj.HourlyP.Add(new AnalogValue(activePowSolar, derHour.Time, modelDataActive.GlobalId, modelDataActive.SynchronousMachine, PowerType.Active, powIncrease, powDecrease)); } break; case FuelType.Wind: { float activePowWind = powCalc.GetActivePowerForWindGenerator(der.NominalP, (float)derHour.WindSpeed); float reactivePowWind = activePowWind * 0.05f; float powIncreaseActive = 0; float powDecreaseActive = 0; float powIncreaseActiveTemp = activePowWind + der.DERFlexibilityP; float powDecreaseActiveTemp = activePowWind - der.DERFlexibilityP; float powIncreaseReactive = 0; float powDecreaseReactive = 0; float powIncreaseReactiveTemp = reactivePowWind + der.DERFlexibilityQ; float powDecreaseReactiveTemp = reactivePowWind - der.DERFlexibilityQ; //Check for active power limit if (powIncreaseActiveTemp >= der.MaxP) { //LogHelper.Log(LogTarget.File, LogService.CalculateHourlyForecast, " WARNING - CalculateHourlyForecast.cs - Wind turbine: " + der.GlobalId + " active power increase value change is higher or equal to max active power. New active power increase value is set to max active power value."); powIncreaseActive = der.MaxP; } else { //LogHelper.Log(LogTarget.File, LogService.CalculateHourlyForecast, " INFO - CalculateHourlyForecast.cs - Wind turbine: " + der.GlobalId + " active power increase value change is lower then max active power. New active power increase value is set regularly."); powIncreaseActive = powIncreaseActiveTemp; } if (powDecreaseActiveTemp <= der.MinP) { //LogHelper.Log(LogTarget.File, LogService.CalculateHourlyForecast, " WARNING - CalculateHourlyForecast.cs - Wind turbine: " + der.GlobalId + " active power decrease value change is lower or equal to min active power. New active power decrease value is set to min active power value."); powDecreaseActive = der.MinP; } else { //LogHelper.Log(LogTarget.File, LogService.CalculateHourlyForecast, " INFO - CalculateHourlyForecast.cs - Wind turbine: " + der.GlobalId + " active power decrease value change is higher then min active power. New active power decrease value is set regularly."); powDecreaseActive = powDecreaseActiveTemp; } //Check for reactive power limit if (powIncreaseReactiveTemp >= der.MaxQ) { //LogHelper.Log(LogTarget.File, LogService.CalculateHourlyForecast, " WARNING - CalculateHourlyForecast.cs - Wind turbine: " + der.GlobalId + " reactive power increase value change is higher or equal to max reactive power. New reactive power increase value is set to max reactive power value."); powIncreaseReactive = der.MaxQ; } else { //LogHelper.Log(LogTarget.File, LogService.CalculateHourlyForecast, " INFO - CalculateHourlyForecast.cs - Wind turbine: " + der.GlobalId + " reactive power increase value change is lower then max reactive power. New reactive power increase value is set regularly."); powIncreaseReactive = powIncreaseReactiveTemp; } if (powDecreaseReactiveTemp <= der.MinQ) { //LogHelper.Log(LogTarget.File, LogService.CalculateHourlyForecast, " WARNING - CalculateHourlyForecast.cs - Wind turbine: " + der.GlobalId + " reactive power decrease value change is lower or equal to min reactive power. New reactive power decrease value is set to min reactive power value."); powDecreaseReactive = der.MinQ; } else { //LogHelper.Log(LogTarget.File, LogService.CalculateHourlyForecast, " INFO - CalculateHourlyForecast.cs - Wind turbine: " + der.GlobalId + " reactive power decrease value change is higher then min reactive power. New reactive power decrease value is set regularly."); powDecreaseReactive = powDecreaseReactiveTemp; } forecastObj.HourlyP.Add(new AnalogValue(activePowWind, derHour.Time, modelDataActive.GlobalId, modelDataActive.SynchronousMachine, PowerType.Active, powIncreaseActive, powDecreaseActive)); forecastObj.HourlyQ.Add(new AnalogValue(reactivePowWind, derHour.Time, modelDataReactive.GlobalId, modelDataReactive.SynchronousMachine, PowerType.Reactive, powIncreaseReactive, powDecreaseReactive)); } break; default: break; } } return(forecastObj); }