Example #1
0
        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);
        }
Example #3
0
        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);
        }
Example #4
0
        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);
            }
        }
Example #5
0
        /// <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);
        }
Example #7
0
        /// <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);
        }
Example #8
0
        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);
        }
Example #9
0
        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);
        }
Example #10
0
        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);
        }
Example #11
0
        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);
        }
Example #15
0
        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);
        }
Example #17
0
        /// <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);
            }
        }
Example #18
0
        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);
        }
Example #19
0
        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);
        }
Example #22
0
        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);
        }