Esempio n. 1
0
        public ArchTechFormulaRequester(ArchTechRequestParams requestParams, IGrouping <enumTypeHierarchy, ArchTechRequestParam> objectIds) : base(requestParams)
        {
            RequestParams = requestParams;
            Errors        = new StringBuilder();
            FormulaIds    = new List <TFormulaParam>();
            var formulasOurSideIds = new HashSet <string>();

            try
            {
                foreach (var rp in objectIds)
                {
                    if (string.IsNullOrEmpty(rp.ID.StringId))
                    {
                        continue;
                    }

                    if (rp.ID.TypeHierarchy == enumTypeHierarchy.Formula_TP_OurSide)
                    {
                        //Это формулы ТП, нужно добрать параметры
                        formulasOurSideIds.Add(rp.ID.StringId);
                    }
                    else
                    {
                        FormulaIds.Add(new TFormulaParam
                        {
                            FormulaID     = rp.ID.StringId,
                            FormulasTable = enumFormulasTable.Info_Formula_Description,
                        });
                    }
                }
            }
            catch (Exception ex)
            {
                Errors.AppendException(ex);
            }

            var errors     = new StringBuilder();
            var formulasTp = TFormulaParam.GetFormulaParamForTPs(new HashSet <TP_ChanelType>(), new List <enumFormulaTPType>(), RequestParams.DtStart, RequestParams.DtEnd, errors,
                                                                 formulaIds: formulasOurSideIds);

            if (errors.Length > 0)
            {
                Errors.Append(errors);
            }

            FormulaIds.AddRange(formulasTp);
        }
Esempio n. 2
0
        protected override bool Execute(CodeActivityContext context)
        {
            var formulaUn = Formula_UN.Get(context);

            if (string.IsNullOrEmpty(formulaUn))
            {
                Error.Set(context, "Не определен идентификатор формулы");
                return(false);
            }

            var fId = new TFormulaParam
            {
                FormulaID     = formulaUn,
                FormulasTable = enumFormulasTable.Info_Formula_Description,
                IsFormulaHasCorrectDescription = true,
            };

            TFormulasResult result = null;

            try
            {
                var res = ARM_Service.FR_GetFormulasResults(new List <TFormulaParam> {
                    fId
                },
                                                            StartDateTime.Get(context),
                                                            EndDateTime.Get(context),
                                                            DiscreteType,
                                                            DataSourceType,
                                                            1,
                                                            IsCoeffEnabled,
                                                            false,
                                                            isPower,
                                                            false,
                                                            UnitDigit, null, false, false);


                if (res != null && res.Result_Values != null && res.Result_Values.Count > 0)
                {
                    var rv = res.Result_Values[0];
                    if (rv != null && rv.Result_Values != null && rv.Result_Values.Count > 0)
                    {
                        result = rv.Result_Values[0];
                        if (result.Val_List != null)
                        {
                            var r = result.Val_List.Accomulate();
                            SummValues.Set(context, r.F_VALUE);
                            Status.Set(context, (int)r.F_FLAG);
                            StatusStr.Set(context, TVALUES_DB.FLAG_to_String(r.F_FLAG, ";"));
                        }
                    }
                }

                if (res.Errors != null)
                {
                    Error.Set(context, res.Errors.ToString());
                }

                FormulaResult.Set(context, result);
            }
            catch (Exception ex)
            {
                Error.Set(context, ex.Message);
                if (!HideException.Get(context))
                {
                    throw ex;
                }
            }
            return(string.IsNullOrEmpty(Error.Get(context)));
        }
Esempio n. 3
0
        /// <summary>
        /// Берем первую попавшуюся модель прогнозирования для объекта
        /// </summary>
        /// <param name="forecastObjectUn"></param>
        /// <returns></returns>
        public static List <TForecastCalculateParams> GetForecastObjectParams(HashSet <string> forecastObjectUns, DateTime dtStart, DateTime dtEnd,
                                                                              int?forecastModelUserSelected, string timeZoneId, StringBuilder errors, EnumUnitDigit unitDigit, enumTimeDiscreteType forecastDiscreteType, bool isReadCalculatedValues)
        {
            var tis      = new List <TI_ChanelType>();
            var formulas = new List <TFormulaParam>();
            var tps      = new List <TP_ChanelType>();
            var nodes    = new List <long>();

            var result = new Dictionary <string, TForecastCalculateParams>();

            var periodsPriorityByForecastObject = new Dictionary <string, Dictionary <string, Queue <PeriodHierarchy> > >();

            if (forecastObjectUns == null)
            {
                return(result.Values.ToList());
            }

            #region Читаем параметры объектов прогнозирования из базы

            var forecastObjectUnsString = string.Join(",", forecastObjectUns);

            try
            {
                using (var db = new LightDBDataContext(Settings.DbConnectionString)
                {
                    ObjectTrackingEnabled = false, //Указываем что это у нас ReadOnly
                    DeferredLoadingEnabled = false,
                    CommandTimeout = 180,
                })
                {
                    var multiResult = db.usp2_ForecastObjectParams(forecastObjectUnsString, dtStart.ClientToServer(timeZoneId), dtEnd.ClientToServer(timeZoneId));

                    //Читаем доступные модели, которым будем считать
                    foreach (var modelsGroupByObject in multiResult.GetResult <usp2_ForecastObjectParamsResult1>().ToList().GroupBy(g => g.ForecastObject_UN))
                    {
                        result[modelsGroupByObject.Key] = new TForecastCalculateParams(modelsGroupByObject.Key, forecastModelUserSelected,
                                                                                       new HashSet <int>(modelsGroupByObject.Where(m => m.ForecastCalculateModel_ID.HasValue).OrderBy(m => m.Priority ?? 1000).Select(m => (int)(m.ForecastCalculateModel_ID ?? 0))));
                    }

                    #region Читаем ТИ, ТП формулы и т.д. для обсчета

                    foreach (var inputParamByObject in multiResult.GetResult <usp2_ForecastObjectParamsResult2>().ToList().GroupBy(g => g.ForecastObject_UN))
                    {
                        TForecastCalculateParams calculateParams;
                        if (!result.TryGetValue(inputParamByObject.Key, out calculateParams) || calculateParams == null)
                        {
                            continue;
                        }

                        calculateParams.DtStart      = dtStart;
                        calculateParams.DtEnd        = dtEnd;
                        calculateParams.DiscreteType = forecastDiscreteType;

                        var periodsByInputParam = new Dictionary <string, Queue <PeriodHierarchy> >();
                        periodsPriorityByForecastObject[inputParamByObject.Key] = periodsByInputParam;

                        foreach (var inputParam in inputParamByObject.GroupBy(g => g.ForecastInputParam_UN))
                        {
                            var periods = new Queue <PeriodHierarchy>();
                            periodsByInputParam[inputParam.Key] = periods;

                            var archiveByInputParam = new ForecastByInputParamArchives(inputParam.Key);
                            calculateParams.ArchivesByInputParam.Add(archiveByInputParam);
                            var isFirst = true;
                            foreach (var physicalParam in inputParam)
                            {
                                bool isFullPeriod;
                                var  period = BuildHalfHoursPeriods(physicalParam, dtStart, dtEnd, timeZoneId, out isFullPeriod);

                                if (isFirst)
                                {
                                    archiveByInputParam.MeasureQuantityType_UN = physicalParam.MeasureQuantityType_UN;
                                    isFirst = false;
                                }

                                //Формула
                                if (!string.IsNullOrEmpty(physicalParam.Formula_UN))
                                {
                                    var formulaParam = new TFormulaParam
                                    {
                                        FormulaID     = physicalParam.Formula_UN,
                                        FormulasTable = enumFormulasTable.Info_Formula_Description,
                                        IsFormulaHasCorrectDescription = true,
                                    };
                                    formulas.Add(formulaParam);
                                    //archiveByInputParam.Formulas.Add(formulaParam);
                                    periods.Enqueue(new PeriodHierarchy
                                    {
                                        Id           = new ID_Hierarchy_Channel(enumTypeHierarchy.Formula, physicalParam.Formula_UN, 0),
                                        IsFullPeriod = isFullPeriod,
                                        IndxStart    = period.Item1,
                                        IndxFinish   = period.Item2,
                                    });

                                    if (isFullPeriod)
                                    {
                                        continue;               //Объект действует на весь период, остальные объекты пропускаем
                                    }
                                }

                                //OPC пока не используется, т.к. не понятно как приводить к получасовкам
                                if (physicalParam.UANode_ID.HasValue)
                                {
                                    //archiveByInputParam.Nodes.Add(physicalParam.UANode_ID.Value);
                                    nodes.Add(physicalParam.UANode_ID.Value);

                                    periods.Enqueue(new PeriodHierarchy
                                    {
                                        Id           = new ID_Hierarchy_Channel(enumTypeHierarchy.UANode, physicalParam.UANode_ID.Value.ToString(), 0),
                                        IsFullPeriod = isFullPeriod,
                                        IndxStart    = period.Item1,
                                        IndxFinish   = period.Item2,
                                    });

                                    if (isFullPeriod)
                                    {
                                        continue;               //Объект действует на весь период, остальные объекты пропускаем
                                    }
                                }

                                //Для остальных нужен канал, если не указан пропускаем
                                //if (!inputParam.ChannelType.HasValue) continue;

                                //ТИ
                                if (physicalParam.TI_ID.HasValue)
                                {
                                    if (!physicalParam.ChannelType.HasValue)
                                    {
                                        errors.Append("Для ТИ {").Append(physicalParam.TI_ID).Append("} нужно указать канал");
                                        continue;
                                    }

                                    var tiId = new TI_ChanelType
                                    {
                                        ChannelType = physicalParam.ChannelType.Value,
                                        TI_ID       = physicalParam.TI_ID.Value,
                                        MsTimeZone  = timeZoneId, //Это возможно не нужно
                                    };
                                    //archiveByInputParam.TiIds.Add(tiId);
                                    tis.Add(tiId);
                                    periods.Enqueue(new PeriodHierarchy
                                    {
                                        Id           = new ID_Hierarchy_Channel(enumTypeHierarchy.Info_TI, physicalParam.TI_ID.Value.ToString(), physicalParam.ChannelType.Value),
                                        IsFullPeriod = isFullPeriod,
                                        IndxStart    = period.Item1,
                                        IndxFinish   = period.Item2,
                                    });

                                    if (isFullPeriod)
                                    {
                                        continue;               //Объект действует на весь период, остальные объекты пропускаем
                                    }
                                }

                                //ТП
                                if (physicalParam.TP_ID.HasValue)
                                {
                                    if (!physicalParam.ChannelType.HasValue)
                                    {
                                        errors.Append("Для ТП {").Append(physicalParam.TP_ID).Append("} нужно указать канал");
                                        continue;
                                    }

                                    var tpId = new TP_ChanelType
                                    {
                                        ChannelType = physicalParam.ChannelType.Value,
                                        TP_ID       = physicalParam.TP_ID.Value,
                                    };
                                    //archiveByInputParam.TpIds.Add(tpId);
                                    tps.Add(tpId);
                                    periods.Enqueue(new PeriodHierarchy
                                    {
                                        Id           = new ID_Hierarchy_Channel(enumTypeHierarchy.Info_TP, physicalParam.TP_ID.Value.ToString(), physicalParam.ChannelType.Value),
                                        IsFullPeriod = isFullPeriod,
                                        IndxStart    = period.Item1,
                                        IndxFinish   = period.Item2,
                                    });
                                }
                            }
                        }
                    }

                    #endregion
                }
            }
            catch (Exception ex)
            {
                errors.Append(ex.Message);
            }

            #endregion

            #region Читаем архивы

            //Пока запрашиваем только получасовки
            var resultCommonTi = new ArchivesValues_List2(tis, dtStart, dtEnd,
                                                          true, false, enumTimeDiscreteType.DBHalfHours, enumTypeInformation.Energy, false,
                                                          unitDigit, enumOVMode.NormalMode, timeZoneId, isReadCalculatedValues: isReadCalculatedValues);

            if (resultCommonTi.Errors != null)
            {
                errors.Append(resultCommonTi.Errors);
            }

            //Запрос значений всех ТП
            var resultCommonTp = new ArchivesTPValues(tps, dtStart, dtEnd, enumBusRelation.PPI_OurSide, enumTimeDiscreteType.DBHalfHours, null, enumTypeInformation.Energy, unitDigit,
                                                      timeZoneId, false, isSupressTpNotFound: true, isReadCalculatedValues: isReadCalculatedValues);
            if (resultCommonTp.Errors != null)
            {
                errors.Append(resultCommonTp.Errors);
            }

            //Все формулы
            var resultCommonFormula = new FormulasResult(formulas, dtStart, dtEnd, enumTimeDiscreteType.DBHalfHours, null, 0, enumTypeInformation.Energy, unitDigit, timeZoneId, //Для описанных здесь формул ед. изм. не учитываем
                                                         true, false, false, false, isReadCalculatedValues: isReadCalculatedValues, ovMode: enumOVMode.NormalMode);              //Для формулы сумму с ОВ считаем всегда!!!
            if (resultCommonFormula.Errors != null)
            {
                errors.Append(resultCommonFormula.Errors);
            }

            //Чтение архивов OPC
            UADataReader resultCommonUAData = null;
            try
            {
                resultCommonUAData = new UADataReader(nodes, dtStart, dtEnd, false, false, false, timeZoneId);
            }
            catch
            { }

            #endregion

            #region Подготовка архивов

            var numberHalfHoursForForecasting = MyListConverters.GetNumbersValuesInPeriod(enumTimeDiscreteType.DBHalfHours, dtStart, dtEnd, timeZoneId);

            result.Values.AsParallel().ForAll(calculateParam => //AsParallel().ForAll()
            {
                //new TVALUES_DB[numberHalfHoursForForecasting].Select(v => new TVALUES_DB(VALUES_FLAG_DB.IsNull, 0)).ToList();

                Dictionary <string, Queue <PeriodHierarchy> > periodsByInputParam;
                if (!periodsPriorityByForecastObject.TryGetValue(calculateParam.ForecastObject_UN, out periodsByInputParam) || periodsByInputParam.Count == 0)
                {
                    return;                                                                                                                                            //Нет параметров для обсчета
                }
                foreach (var paramArchives in calculateParam.ArchivesByInputParam)
                {
                    Queue <PeriodHierarchy> periods;
                    if (!periodsByInputParam.TryGetValue(paramArchives.ForecastInputParamUn, out periods) || periods.Count == 0)
                    {
                        continue;                                                                                                          //Нет параметров для обсчета
                    }
                    //var period = periods.Dequeue(); //Первый объект в интервале
                    PeriodHierarchy period = null;
                    var halfHours          = new List <TVALUES_DB>();
                    for (var hh = 0; hh < numberHalfHoursForForecasting; hh++)
                    {
                        if (!PeriodInHalfHour(ref period, periods, hh, resultCommonTi, resultCommonFormula,
                                              resultCommonTp, resultCommonUAData) || period.Archives == null)
                        {
                            halfHours.Add(new Servers.Calculation.DBAccess.Interface.Data.TVALUES_DB(VALUES_FLAG_DB.IsNull, 0)); //Получасовка не входит в наш диапазон, или нет архива
                            continue;
                        }

                        var aVal = period.Archives.ElementAtOrDefault(hh);
                        if (aVal == null)
                        {
                            aVal = new Servers.Calculation.DBAccess.Interface.Data.TVALUES_DB(VALUES_FLAG_DB.IsNull, 0); //Непонятная ситуация, помечаем как отсутствующие
                        }

                        var cVal = halfHours.ElementAtOrDefault(hh);
                        if (cVal == null)
                        {
                            cVal = new Servers.Calculation.DBAccess.Interface.Data.TVALUES_DB(aVal.F_FLAG, aVal.F_VALUE);
                            halfHours.Add(cVal);
                        }
                        else
                        {
                            cVal.F_VALUE = aVal.F_VALUE;
                            cVal.F_FLAG  = aVal.F_FLAG;
                        }
                    }


                    paramArchives.Archives.AddRange(MyListConverters.ConvertHalfHoursToOtherList(forecastDiscreteType, halfHours,
                                                                                                 dtStart, dtEnd, timeZoneId).Select(v => new Servers.Calculation.DBAccess.Interface.Data.TVALUES_DB(v.F_FLAG, v.F_VALUE)));
                }
            });

            #endregion

            return(result.Values.ToList());
        }