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); }
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))); }
/// <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()); }