Example #1
0
        public static StockpilePosition GetStockpilePosition(Colony colony)
        {
            var sp = new StockpilePosition();
            var cs = ColonyState.GetColonyState(colony);

            if (cs.Positions.TryGetValue(StockpileBlock.Name, out var pos))
            {
                sp.Position = pos;
                var currentPeriod = PeriodFactory.GetTimePeriod(colony);
                sp.Min = pos.Add(StockpileBlock.StockpileSizes[currentPeriod].Item1);
                sp.Max = pos.Add(StockpileBlock.StockpileSizes[currentPeriod].Item2);
            }

            return(sp);
        }
        /// <summary>
        /// Делаем расчет по формуле
        /// </summary>
        /// <param name="formulaId">Идентификатор формулы</param>
        /// <param name="inDataTI">Данные по ТИ</param>
        /// <param name="inDataIntegrals">Интегральные данные</param>
        /// <param name="inDataTP">Данные по ТП</param>
        /// <param name="inDataSection">Данные по сечению</param>
        /// <param name="indxStart">Начальный индекс, с которого формула активна</param>
        /// <param name="indxEnd">Конечный индекс</param>
        /// <param name="unitDigitCoeff">Коэфф. дорасчета ед. измерения</param>
        /// <param name="formulaTPType">Тип формулы ТП</param>
        /// <param name="formulasTable">Табличный тип формулы (обычная или ТП)</param>
        /// <param name="tpId">Идентификатор ТП к которой привязана формула</param>
        /// <param name="rangeInSectionForEntirePeriod">Используется ли формула в сечении, где действует ограничение на период действия ТП</param>
        /// <param name="rangeIndexesInSectionList">Индексы с которого действуют ТП в сечении</param>
        /// <param name="hiHiSetpoint">Верхняя уставка, по которой проверяем формулу</param>
        /// <param name="loLoSetpoint">Нижняя уставка, по которой проверяем формулу</param>
        /// <param name="inFormulaConstants">Данные по константам, используемым в формуле</param>
        /// <param name="formulasDisabledPeriods">Индексы получасовок между которыми формула не считается</param>
        /// <returns></returns>
        public List <TVALUES_DB> InterpretFormula(string formulaId
                                                  , bool isSumm
                                                  , int indxStart, int indxEnd, double unitDigitCoeff, enumClientFormulaTPType formulaTPType,
                                                  enumFormulasTable formulasTable, bool rangeInSectionForEntirePeriod = true,
                                                  IEnumerable <IPeriodIndexesTpInSection> rangeIndexesInSectionList   = null, double?hiHiSetpoint = null, double?loLoSetpoint = null,
                                                  IEnumerable <IFormulasDisabledPeriod> formulasDisabledPeriods       = null,
                                                  string measureUnitUn = null, PeriodFactory manualEnteredHalfHourIndexes = null)
        {
            var isCalculateBetweenIndexes = !InterpretatorParams.TechProfilePeriod.HasValue && (indxStart > 0 || indxEnd < (InterpretatorParams.NumbersHalfHours - 1));

            var isExistDisablePeriod = formulasDisabledPeriods != null && formulasDisabledPeriods.ToList().Count > 0;

            _recursionCallStack.Clear();

            double?coeff;

            if (string.IsNullOrEmpty(measureUnitUn))
            {
                if (unitDigitCoeff > 1)
                {
                    coeff = 1 / unitDigitCoeff;
                    if (InterpretatorParams.TypeInformation == enumTypeInformation.Power)
                    {
                        coeff *= 2;
                    }
                }
                else if (InterpretatorParams.TypeInformation == enumTypeInformation.Power)
                {
                    coeff = 2;
                }
                else
                {
                    coeff = null;
                }
            }
            else
            {
                coeff = null;
            }

            _formulasTable = formulasTable;

            var formula = GetFormulaByID(formulaId);

            var polskaParams = new PolskaParams(formula.F_ID, _formulasTable,
                                                InterpretatorParams.StartDateTime, InterpretatorParams.EndDateTime, InterpretatorParams.DiscreteType, InterpretatorParams.NumbersHalfHours, formula.UnitDigit, InterpretatorParams.TechProfilePeriod.HasValue);

            var parser = ComposeExpressionPolskaya(formula, polskaParams, indxStart, indxEnd, InterpretatorParams.NumbersHalfHours, isCalculateBetweenIndexes);

            parser.Compile();

            //var result = new List<TVALUES_DB>();

            using (var accamulator = new FormulaAccamulator(InterpretatorParams.IntervalTimeList, isSumm, formula.UnitDigit))
            {
                //Считаем всегда по получасовкам
                for (var halfHourIndex = 0; halfHourIndex < InterpretatorParams.NumbersHalfHours; halfHourIndex++)
                {
                    // рассчет по формуле
                    if (!isCalculateBetweenIndexes || halfHourIndex >= indxStart && halfHourIndex <= indxEnd)
                    {
                        #region Ограничиваем диапазоном в сечении

                        if (!rangeInSectionForEntirePeriod)
                        {
                            if (!rangeIndexesInSectionList.Any(range => range.StartIndex <= halfHourIndex && (range.FinishIndex ?? InterpretatorParams.NumbersHalfHours - 1) >= halfHourIndex))
                            {
                                accamulator.Accamulate(0, VALUES_FLAG_DB.TpNotInSectionRange, enumClientFormulaTPType.TpNotInSectionRange);
                                continue;
                            }
                        }

                        #endregion

                        #region Ограничиваем когда формула заблокирована напряму таблицей Info_Formula_DisabledPeriod

                        if (isExistDisablePeriod)
                        {
                            if (formulasDisabledPeriods.Any(range => halfHourIndex >= range.StartIndx && halfHourIndex <= range.FinishIndx))
                            {
                                accamulator.Accamulate(0, VALUES_FLAG_DB.FormulaNotInRange);
                                //result.Add(new Formula_VALUES_DB(VALUES_FLAG_DB.FormulaNotInRange, 0));
                                continue;
                            }
                        }

                        #endregion

                        #region Ограничиваем периодами, когда данные были введены вручную (считать не нужно)

                        if (manualEnteredHalfHourIndexes != null && manualEnteredHalfHourIndexes.HavePeriod(halfHourIndex))
                        {
                            //result.Add(new Formula_VALUES_DB(VALUES_FLAG_DB.None, 0));
                            accamulator.Accamulate(0, VALUES_FLAG_DB.None);
                            continue;
                        }

                        #endregion

                        var val = parser.EvaluateStringValue(halfHourIndex);

                        #region Обрабатываем уставки

                        if (hiHiSetpoint.HasValue && val.F_VALUE >= hiHiSetpoint)
                        {
                            val.F_FLAG |= VALUES_FLAG_DB.HiHiSetpointExcess;
                        }
                        if (loLoSetpoint.HasValue && val.F_VALUE <= loLoSetpoint)
                        {
                            val.F_FLAG |= VALUES_FLAG_DB.LoLoSetpointExcess;
                        }

                        #endregion

                        //Учитываем что это мощность или размерность (кило, мега и т.д.)
                        if (coeff.HasValue)
                        {
                            val.F_VALUE *= coeff.Value;
                        }

                        val.FormulaTPType = formulaTPType;

                        accamulator.Accamulate(val.F_VALUE, val.F_FLAG, formulaTPType);
                        //result.Add(val.F_VALUE, val.F_FLAG);
                    }
                    else
                    {
                        accamulator.Accamulate(0, VALUES_FLAG_DB.FormulaNotInRange, enumClientFormulaTPType.NotInRange);
                        //Ограничения по времени действия формулы
                        //result.Add(new Formula_VALUES_DB(VALUES_FLAG_DB.FormulaNotInRange, 0, enumClientFormulaTPType.NotInRange));
                    }
                }

                return(accamulator.Result);
            }

            //return result;
        }