Exemplo n.º 1
0
        private static void ValidateSetStatus(IntervalReading intervalReading, List <Exception> exceptions)
        {
            if (intervalReading.StatusFNN == null && !intervalReading.StatusPTB.HasValue)
            {
                exceptions.Add(new InvalidOperationException("Das Element \"IntervalReading\" muss mindestens \"StatusFNN\" oder \"StatusPTB\" mit einem gültigen Wert enthalten."));
                return;
            }

            if (intervalReading.StatusFNN != null && !intervalReading.StatusPTB.HasValue)
            {
                if (string.IsNullOrWhiteSpace(intervalReading.StatusFNN.Status))
                {
                    exceptions.Add(new InvalidOperationException("Das Element \"IntervalReading\" muss mindestens \"StatusFNN\" oder \"StatusPTB\" mit einem gültigen Wert enthalten."));
                }
                else
                {
                    if (!intervalReading.StatusFNN.ValidateFNNStatus())
                    {
                        exceptions.Add(new InvalidOperationException("Das Element \"StatusFNN\" hat keinen gültigen Wert."));
                    }
                }
            }
            else if (intervalReading.StatusFNN == null && intervalReading.StatusPTB.HasValue)
            {
                ValidateIntervalReadingStatusPTB(intervalReading.StatusPTB, exceptions);
            }
        }
Exemplo n.º 2
0
        private static void Taf1RegisterMeterReading(this MeterReading meterReading, MeterReading oml, BillingPeriod billingPeriod, MeterReadingConfig meterReadingConfig)
        {
            var intervalBlock  = InitIntervalBlockWithInterval(billingPeriod.Begin, (DateTime)billingPeriod.End);
            var period         = meterReadingConfig.Taf1PeriodInMonth;
            var requiredValues = GetRequiredIntervalReadingsFromOML(oml, billingPeriod.Begin, (DateTime)billingPeriod.End);

            var timestamp = billingPeriod.Begin.AddMonths(period);
            var initValue = requiredValues.FirstOrDefault(val => val.TimePeriod.Start == billingPeriod.Begin).Value;
            var value     = GetNextValue(initValue, requiredValues, timestamp, (DateTime)billingPeriod.End);

            while (timestamp <= billingPeriod.End)
            {
                var ir = new IntervalReading()
                {
                    TimePeriod = new Interval()
                    {
                        Duration = 0,
                        Start    = timestamp
                    },
                    Value = value
                };

                SetStatusWord(ir, meterReadingConfig);
                ir.IntervalBlock = intervalBlock;
                intervalBlock.IntervalReadings.Add(ir);
                timestamp = timestamp.AddMonths(period);
                value     = GetNextValue(initValue, requiredValues, timestamp, (DateTime)billingPeriod.End);
            }

            intervalBlock.MeterReading = meterReading;
            meterReading.IntervalBlocks.Add(intervalBlock);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Gets the CSS class for the status icon from the specified interval reading.
        /// </summary>
        /// <param name="reading">The interval reading.</param>
        /// <returns>The CSS class of the status icon.</returns>
        public static string ToStatusIcon(this IntervalReading reading)
        {
            if (reading == null || (reading.StatusPTB == null && reading.StatusFNN == null))
            {
                return(string.Empty);
            }

            var status = reading.StatusPTB ?? reading.StatusFNN.MapToStatusPtb();

            return(status.ToStatusIcon());
        }
Exemplo n.º 4
0
        public HistoricConsumption(IntervalReading startReading, IntervalReading endReading, DateTime begin, DateTime end, TimeUnit unitOfTime)
        {
            if (startReading?.Value != null && endReading?.Value != null)
            {
                this.Value = endReading.Value - startReading.Value;
            }

            this.UnitOfTime = unitOfTime;
            this.Begin      = begin;
            this.End        = end;
        }
Exemplo n.º 5
0
 private static void SetStatusWord(IntervalReading ir, MeterReadingConfig config)
 {
     if (config.UsedStatus == "FNN")
     {
         ir.StatusFNN = new StatusFNN(GetStatusFNN());
     }
     else if (config.UsedStatus == "PTB")
     {
         ir.StatusPTB = (StatusPTB)GetRandomNumber(0, 4);
     }
 }
Exemplo n.º 6
0
        /// <summary>
        /// If a intervalReading to the tariff change timestamp is needed, this method will be called.
        /// </summary>
        /// <param name="meterReading">The raw data.</param>
        /// <param name="end">The date for the meterReading</param>
        /// <param name="index">the index of the parent loop</param>
        /// <returns>An intervalReading or null</returns>
        public (IntervalReading reading, DateTime end) SetIntervalReading(MeterReading meterReading, DateTime end, int index, int dayTimeProfilesCount)
        {
            var date    = LocalSetLastReading(end, index, dayTimeProfilesCount);
            var reading = meterReading.GetIntervalReadingFromDate(date);

            // If there is a gap at 0:00 o'clock the next day
            if (date > end && (reading == null || !IsStatusValid(reading)))
            {
                date    = end;
                reading = meterReading.GetIntervalReadingFromDate(date);
            }

            return(reading, date);
        }
Exemplo n.º 7
0
        /// <summary>
        /// This value is needed if there is a gap between 2 days.
        /// </summary>
        /// <param name="latestReading">The current latest reading</param>
        /// <param name="reading">The current reading with a possible new value for latestReading</param>
        /// <returns>The latest reading value</returns>
        public long GetLatestReading(long latestReading, IntervalReading reading)
        {
            var result = latestReading;

            if (reading != null && IsStatusValid(reading))
            {
                if (reading.Value.HasValue)
                {
                    result = reading.Value > latestReading ? (long)reading.Value : latestReading;
                }
            }

            return(result);
        }
Exemplo n.º 8
0
        /// <summary>
        /// Check if the IntervalReading instance has an valid status
        /// </summary>
        /// <param name="reading">The IntervalReading object to check.</param>
        /// <returns>True if the status is valid.</returns>
        private bool IsStatusValid(IntervalReading reading)
        {
            if (reading != null)
            {
                var fnnStatusToPtbStatus = reading.StatusFNN?.MapToStatusPtb();
                var ptbStatus            = reading.StatusPTB;

                return(fnnStatusToPtbStatus != StatusPTB.CriticalTemporaryError &&
                       fnnStatusToPtbStatus != StatusPTB.FatalError &&
                       ptbStatus != StatusPTB.CriticalTemporaryError &&
                       ptbStatus != StatusPTB.FatalError);
            }

            return(false);
        }
Exemplo n.º 9
0
        /// <summary>
        /// Converts the status of the interval reading to the PTB status text.
        /// </summary>
        /// <param name="reading">The interval reading.</param>
        /// <param name="count">The count used for the distinction between plural and singular.</param>
        /// <returns>The status text.</returns>
        public static string ToStatusString(this IntervalReading reading, int count = 1)
        {
            if (reading == null || (reading.StatusPTB == null && reading.StatusFNN == null))
            {
                return(string.Empty);
            }

            if (reading.StatusFNN != null)
            {
                return(GetFnnStatusString(reading.StatusFNN, count));
            }

            var status = reading.StatusPTB ?? reading.StatusFNN.MapToStatusPtb();

            return(status.GetStatusString(count));
        }
Exemplo n.º 10
0
        private static void Taf2RegisterMeterReading(this MeterReading meterReading, MeterReading oml, BillingPeriod billingPeriod, MeterReadingConfig meterReadingConfig, List <Taf2Data> taf2Data)
        {
            var intervalBlock  = InitIntervalBlockWithInterval(billingPeriod.Begin, (DateTime)billingPeriod.End);
            var ObisCode       = new ObisId(oml.ReadingType.ObisCode);
            var taf2           = taf2Data.FirstOrDefault(t => t.ObisID.ToHexString() == ObisCode.ToHexString());
            var requiredValues = GetRequiredIntervalReadingsFromOML(oml, billingPeriod.Begin, (DateTime)billingPeriod.End);

            int value = 0;

            if (new ObisId(meterReading.ReadingType.ObisCode).E == 0)
            {
                foreach ((DateTime timestamp, int tariff, int value)item in taf2.Data)
                {
                    if (item.timestamp >= billingPeriod.Begin && item.timestamp <= (DateTime)billingPeriod.End)
                    {
                        value = value + item.value;
                    }
                }
            }
            else
            {
                foreach ((DateTime timestamp, int tariff, int value)item in taf2.Data)
                {
                    if (item.timestamp >= billingPeriod.Begin && item.timestamp <= (DateTime)billingPeriod.End && item.tariff == meterReadingConfig.Taf2TariffStage)
                    {
                        value = value + item.value;
                    }
                }
            }

            var ir = new IntervalReading()
            {
                TimePeriod = new Interval()
                {
                    Duration = (uint)(billingPeriod.End - billingPeriod.Begin)?.TotalSeconds,
                    Start    = billingPeriod.Begin
                },
                Value = value
            };

            SetStatusWord(ir, meterReadingConfig);
            ir.IntervalBlock = intervalBlock;
            intervalBlock.IntervalReadings.Add(ir);
            intervalBlock.MeterReading = meterReading;
            meterReading.IntervalBlocks.Add(intervalBlock);
        }
Exemplo n.º 11
0
        // Validation of an IntervalReading instance
        private static void ValidateIntervalReading(IntervalReading intervalReading, List <Exception> exceptions)
        {
            if (intervalReading.TimePeriod == null)
            {
                exceptions.Add(new InvalidOperationException("Das Element \"IntervalReading\" muss das Element \"TimePeriod\" enthalten."));
            }
            else
            {
                ValidateInterval(intervalReading.TimePeriod, "timePeriod", exceptions);
            }

            if (!intervalReading.Value.HasValue)
            {
                exceptions.Add(new InvalidOperationException("Das Element \"value\" enthält keinen gültigen Wert."));
            }

            ValidateSetStatus(intervalReading, exceptions);
        }
Exemplo n.º 12
0
        /// <summary>
        /// Gets the background color of the status from specified interval reading.
        /// </summary>
        /// <param name="reading">The interval reading.</param>
        /// <returns>The CSS class.</returns>
        public static string ToStatusBackground(this IntervalReading reading)
        {
            if (reading == null)
            {
                return(string.Empty);
            }

            if (reading.Value == null)
            {
                return("bg-warning");
            }

            if (reading.StatusPTB == null && reading.StatusFNN == null)
            {
                return(string.Empty);
            }

            var status = reading.StatusPTB ?? reading.StatusFNN.MapToStatusPtb();

            switch (status)
            {
            case StatusPTB.NoError:
                return(string.Empty);

            case StatusPTB.Warning:
                return("bg-warning");

            case StatusPTB.TemporaryError:
                return("bg-warning");

            case StatusPTB.CriticalTemporaryError:
                return("bg-warning");

            case StatusPTB.FatalError:
                return("bg-danger");

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
Exemplo n.º 13
0
        private static void OriginalValueList(this MeterReading meterReading, HanAdapterExampleConfig hanConfiguration, MeterReadingConfig meterReadingConfig, List <Taf2Data> taf2Data)
        {
            var intervalBlock = InitIntervalBlockWithInterval((DateTime)hanConfiguration.Start, (DateTime)hanConfiguration.End);
            var taf2          = new Taf2Data(new ObisId(meterReading.ReadingType.ObisCode));

            var value     = meterReadingConfig.OMLInitValue;
            var preValue  = value;
            var timestamp = intervalBlock.Interval.Start.ToUniversalTime();

            var end = intervalBlock.Interval.GetEnd().GetDateWithoutSeconds().ToUniversalTime();

            while (timestamp <= end)
            {
                var ir = new IntervalReading()
                {
                    TimePeriod = new Interval()
                    {
                        Duration = 0,
                        Start    = timestamp.ToLocalTime()
                    },
                    Value = value
                };

                if (preValue != value)
                {
                    taf2.Data.Add((timestamp.ToLocalTime(), GetRandomNumber(0, meterReadingConfig.Taf2TariffStages), value - preValue));
                }

                preValue  = value;
                value     = value + GetRandomNumber(1, hanConfiguration.XmlConfig.MaxConsumptionValue);
                timestamp = timestamp.AddSeconds(meterReadingConfig.PeriodSeconds.Value).GetDateWithoutSeconds();
                SetStatusWord(ir, meterReadingConfig);
                ir.IntervalBlock = intervalBlock;
                intervalBlock.IntervalReadings.Add(ir);
            }

            taf2Data.Add(taf2);
            intervalBlock.MeterReading = meterReading;
            meterReading.IntervalBlocks.Add(intervalBlock);
        }
Exemplo n.º 14
0
 /// <summary>
 /// This method is used to create an empty endReading object
 /// </summary>
 /// <returns></returns>
 public static (IntervalReading reading, DateTime end) SetConcreteIntervalReading(IntervalReading reading, DateTime end)
 {
     return(reading, end);
 }
Exemplo n.º 15
0
        /// <summary>
        /// The main calculation method for the accounting period in Taf-1.
        /// </summary>
        /// <param name="supplier">Contains the calculation data.</param>
        /// <param name="meterReading">The MeterReading instance with the raw data.</param>
        /// <param name="startReading">The intervalReading at the beginning of the section.</param>
        /// <param name="endReading">The intervalReading at the end of the section.</param>
        /// <param name="tariffId">The valid tariffId.</param>
        /// <returns>The calculated AccountingSection</returns>
        public AccountingMonth GetSection(UsagePointLieferant supplier, MeterReading meterReading, IntervalReading startReading, IntervalReading endReading, ushort tariffId)
        {
            var registers = supplier.GetRegister();

            this.UpdateReadingTypeFromOriginalValueList(registers);

            var section = new AccountingMonth(registers)
            {
                Reading = new Reading()
                {
                    Amount = startReading.Value, ObisCode = new ObisId(meterReading.ReadingType.ObisCode)
                }
            };

            var  start  = startReading.TargetTime.Value;
            var  end    = endReading.TargetTime.Value;
            long amount = (long)(endReading.Value - startReading.Value);

            var range = new MeasuringRange(start, end, tariffId, amount);

            section.Add(range);
            section.Start = start;

            return(section);
        }
Exemplo n.º 16
0
 private static void CheckIntervalReading(IntervalReading ir, string targetTime, string captureTime, long value)
 {
     Assert.AreEqual(ir.Value, value);
     Assert.AreEqual(targetTime, ir.TargetTime?.ToString("yyyy-MM-ddTHH:mm:ssK"));
     Assert.AreEqual(captureTime, ir.CaptureTime.ToString("yyyy-MM-ddTHH:mm:ssK"));
 }
Exemplo n.º 17
0
        /// <summary>
        /// Searches the next valid startReading (In case the first value or values of the day are gaps)
        /// </summary>
        /// <param name="start">the current timestamp.</param>
        /// <param name="dayTimeProfiles">The dayTimeProfiles for the current day.</param>
        /// <param name="profile">The specialDayProfile of the current day.</param>
        /// <param name="meterReading">The meterReading object of the current original value list.</param>
        /// <param name="currentDay">The current AccountingDay object.</param>
        /// <param name="dtpIndex">The current dayTimeProfiles index.</param>
        /// <param name="latestReading">The current meterReading value.</param>
        /// <param name="lastTariffId">The last valid tariff id.</param>
        /// <returns>The next valid start value.</returns>
        public (IntervalReading startReading, int index, long latestReading, ushort tariffId) GetStartReading(DateTime start, List <DayTimeProfile> dayTimeProfiles,
                                                                                                              SpecialDayProfile profile, MeterReading meterReading, AccountingDay currentDay, int dtpIndex, long latestReading, ushort lastTariffId)
        {
            var dayStart     = start;
            var startReading = new IntervalReading();
            var index        = dtpIndex;

            for (int i = 1; i < dayTimeProfiles.Count; i++)
            {
                start        = ModelExtensions.GetDateTimeFromSpecialDayProfile(profile, dayTimeProfiles[i]);
                startReading = meterReading.GetIntervalReadingFromDate(start);

                // If the gap reaches the next tariff change
                if (dayTimeProfiles[i].TariffNumber != lastTariffId && lastTariffId != 63)
                {
                    lastTariffId = 63;
                }

                // Checks if a startReading is found
                if (startReading != null && IsStatusValid(startReading))
                {
                    currentDay.Add(new MeasuringRange()
                    {
                        Start    = dayStart,
                        End      = start,
                        Amount   = (startReading.Value.Value - latestReading),
                        TariffId = lastTariffId
                    }, new ObisId(meterReading.ReadingType.ObisCode));

                    index         = i;
                    latestReading = GetLatestReading(latestReading, startReading);
                    lastTariffId  = (ushort)dayTimeProfiles[i].TariffNumber;
                    break;
                }
                else
                {
                    index = i;
                }
            }

            // if no startReading for the whole day was found, set index to 96
            if ((startReading == null || !IsStatusValid(startReading)) && index == dayTimeProfiles.Count - 1)
            {
                var nextDay0OClock = start.AddSeconds(900);
                startReading = meterReading.GetIntervalReadingFromDate(nextDay0OClock);

                // Check if a value for the next day at 0:00 o Clock exists
                if (startReading != null && IsStatusValid(startReading))
                {
                    currentDay.Add(new MeasuringRange()
                    {
                        Start    = dayStart,
                        End      = nextDay0OClock,
                        Amount   = startReading.Value.Value - latestReading,
                        TariffId = lastTariffId
                    }, new ObisId(meterReading.ReadingType.ObisCode));
                }
                index = dayTimeProfiles.Count;
            }

            return(startReading, index, latestReading, lastTariffId);
        }
Exemplo n.º 18
0
        /// <summary>
        /// Calculates the next valid range for the current day
        /// </summary>
        /// <param name="reading">The IntervalReading at the end of the new range.</param>
        /// <param name="endCurrentReading">The end date of the current range.</param>
        /// <param name="startReading">The IntervalReading at the start of the new range.</param>
        /// <param name="start">The start date of the current range.</param>
        /// <param name="end">The global end date of the current day.</param>
        /// <param name="dayTimeProfiles">The dayTimeProfiles for the current day.</param>
        /// <param name="meterReading">The meterReading object of the current original value list.</param>
        /// <param name="profile">The current SpecialDayProfile.</param>
        /// <param name="currentDay">The current AccountingDay object.</param>
        /// <param name="i">The current index value of the parent loop.</param>
        /// <param name="latestReading">The current meterReading value.</param>
        /// <param name="latestTariffId">The last valid tariff id.</param>
        /// <returns>The rangeData of the found range</returns>
        public (IntervalReading reading, MeasuringRange range, int index, long latestReading) GetNextRange(IntervalReading reading,
                                                                                                           DateTime endCurrentReading, IntervalReading startReading, DateTime start, DateTime end, List <DayTimeProfile> dayTimeProfiles,
                                                                                                           MeterReading meterReading, SpecialDayProfile profile, AccountingDay currentDay, int i, long latestReading, ushort latestTariffId)
        {
            var endReading = SetConcreteIntervalReading(reading, endCurrentReading);
            var range      = new MeasuringRange();

            // Normal situation: reading is valid.
            if (endReading.reading != null && IsStatusValid(endReading.reading))
            {
                range = new MeasuringRange(start, endReading.end, (ushort)dayTimeProfiles[i - 1].TariffNumber,
                                           (endReading.reading.Value.Value - startReading.Value.Value));
            }
            else // A gap was found
            {
                // Looking for the next valid IntervalReading
                var result = FindLastValidTime(start, end, profile, dayTimeProfiles, meterReading, i - 1);
                endReading = SetIntervalReading(meterReading, result.end, result.index, dayTimeProfiles.Count);

                if (result.end < end && endReading.reading != null) // An IntervalReading was found which is bigger than startReading but smaller than the detected gap.
                {
                    range = new MeasuringRange(start, endReading.end, (ushort)dayTimeProfiles[result.index].TariffNumber,
                                               (endReading.reading.Value.Value - startReading.Value.Value));
                }
                else
                {
                    // Count in error register
                    if (endReading.reading != null && IsStatusValid(endReading.reading))
                    {
                        range = new MeasuringRange(start, endReading.end, (endReading.reading.Value.Value - startReading.Value.Value));
                    }
                    else
                    {
                        // No closing valid IntervalReading for the current day was found (There was a gap at the last tariff change)
                        latestTariffId     = 63;
                        endReading.reading = startReading;     // No valid IntervalReading was found. Reset range to mark it as invalid.
                    }
                }

                // 1 Measurement period at tariff change is missing
                if ((i - 1) == result.index)
                {
                    latestReading  = this.GetLatestReading(latestReading, endReading.reading);
                    latestTariffId = range.TariffId;

                    currentDay.Add(range, new ObisId(meterReading.ReadingType.ObisCode));
                    var j           = result.index;
                    var nextDate    = ModelExtensions.GetDateTimeFromSpecialDayProfile(profile, dayTimeProfiles[j + 1]);
                    var nextReading = SetIntervalReading(meterReading, nextDate, j + 1, dayTimeProfiles.Count);
                    while (nextReading.reading == null || !IsStatusValid(nextReading.reading))
                    {
                        j++;
                        if (j < dayTimeProfiles.Count - 1)
                        {
                            nextDate = ModelExtensions.GetDateTimeFromSpecialDayProfile(profile,
                                                                                        dayTimeProfiles[j + 1]);
                            nextReading = SetIntervalReading(meterReading, nextDate, j + 1, dayTimeProfiles.Count);
                        }
                        else
                        {
                            nextDate = ModelExtensions.GetDateTimeFromSpecialDayProfile(profile,
                                                                                        dayTimeProfiles[j]);
                            nextReading = SetIntervalReading(meterReading, nextDate, j, dayTimeProfiles.Count);

                            if (nextReading.reading == null || !IsStatusValid(endReading.reading))
                            {
                                nextReading = endReading;
                                break;
                            }
                        }
                    }

                    // Count in error register
                    range        = new MeasuringRange(endReading.end, nextReading.end, (nextReading.reading.Value.Value - endReading.reading.Value.Value));
                    endReading   = nextReading;
                    result.index = j + 1;
                }

                // Protect for the special case i == dayTimeProfiles.Count -1 because it could lead to an endless loop.
                if (i != dayTimeProfiles.Count - 1)
                {
                    i = result.index;
                }
            }

            // Check if the range object is empty
            if (this.IsRangeEmpty(range))
            {
                range.TariffId = latestTariffId;
            }

            return(endReading.reading, range, i, latestReading);
        }