コード例 #1
0
        public void TestObisIdEquals()
        {
            var a = new ObisId("1-0:1.8.0*255");
            var b = new ObisId("1-0:1.8.0*255");
            var c = new ObisId("1-0:1.8.1*255");

            var d = a;

            Assert.IsTrue(a == b);
            Assert.IsTrue(a == d);
            Assert.IsFalse(a == c);
            Assert.IsTrue(a != c);
            Assert.IsFalse(a != b);

            Assert.IsTrue(a == "1-0:1.8.0*255");
            Assert.IsFalse(a == "1-0:1.8.1*255");
            Assert.IsFalse(a == "xxxxx");
            Assert.IsTrue(a != "xxxxx");

            Assert.IsTrue("1-0:1.8.0*255" == a);
            Assert.IsFalse("1-0:1.8.1*255" == a);

            Assert.IsFalse(a.Equals("test"));
            Assert.IsFalse(a.Equals(null));
            Assert.IsTrue(a.Equals(b));
            Assert.IsFalse(a.Equals(c));
            Assert.IsTrue(a.Equals(a));
            Assert.IsTrue(a.Equals(d));
        }
コード例 #2
0
        public MeasuringRange(DateTime start, DateTime end, MeterReading mr, int amount)
        {
            this.Start = start;
            this.End   = end;
            var obis = new ObisId(mr.ReadingType.ObisCode);

            this.TariffId = obis.E;
            this.Amount   = amount;
        }
コード例 #3
0
        /// <summary>
        /// For each original value list exactly one dayProfile number is allowed.
        /// </summary>
        /// <param name="dayProfiles">The list of DayProfiles.</param>
        /// <param name="obisId">The corresponding obisId.</param>
        /// <param name="analysisProfile">The AnalysisProfile which contain the needed tariff stages.</param>
        /// <returns></returns>
        public ushort GetDayProfileNumber(List <DayProfile> dayProfiles, ObisId obisId, AnalysisProfile analysisProfile)
        {
            var profileList = dayProfiles.GetValidDayProfilesForMeterReading(obisId, analysisProfile.TariffStages);

            if (profileList == null || profileList.Count != 1)
            {
                throw new InvalidOperationException($"Es sind {profileList?.Count} Tagesprofile vorhanden. Es ist genau 1 Tagesprofil erlaubt.");
            }

            return((ushort)profileList.First());
        }
コード例 #4
0
        public void TestObisId3()
        {
            var target = new ObisId("1-0:1.8.0");

            Assert.AreEqual(1, target.A);
            Assert.AreEqual(0, target.B);
            Assert.AreEqual(1, target.C);
            Assert.AreEqual(8, target.D);
            Assert.AreEqual(0, target.E);
            Assert.AreEqual(255, target.F);

            Assert.AreEqual("1-0:1.8.0*255", target.ToString());
        }
コード例 #5
0
        public void TestObisId4()
        {
            var a = new ObisId("1-0:1.8.0*254");
            var b = new ObisId(a);

            Assert.AreEqual(1, b.A);
            Assert.AreEqual(0, b.B);
            Assert.AreEqual(1, b.C);
            Assert.AreEqual(8, b.D);
            Assert.AreEqual(0, b.E);
            Assert.AreEqual(254, b.F);

            Assert.AreEqual("1-0:1.8.0*254", b.ToString());
        }
コード例 #6
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);
        }
コード例 #7
0
        /// <summary>
        /// This method is a DayProfile filter.
        /// </summary>
        /// <param name="dayProfiles">A list of all dayProfiles.</param>
        /// <param name="mrObisId">The ObisId of the current MeterReading.</param>
        /// <param name="tariffStages">A List of all tariff stages.</param>
        /// <returns>All valid DayProfiles which contains just the allowed tariff stages.</returns>
        public static List <ushort?> GetValidDayProfilesForMeterReading(this List <DayProfile> dayProfiles, ObisId mrObisId, List <TariffStage> tariffStages)
        {
            var validDayProfiles = new List <ushort?>();
            var tariffIdList     = new List <ushort?>();

            if (mrObisId == default(ObisId) || tariffStages == null)
            {
                throw new ArgumentNullException("Die ObisId ist nicht gesetzt oder es sind keine Tarifstufen vorhanden.");
            }

            if (tariffStages.Count < 1 || dayProfiles.Count < 1)
            {
                throw new ArgumentException("Es wurden keine Tarifstufen oder Tagesprofile gefunden.");
            }

            foreach (TariffStage stage in tariffStages)
            {
                var obisId = new ObisId(stage.ObisCode);

                if (mrObisId.C == obisId.C)
                {
                    tariffIdList.Add(stage.TariffNumber);
                }
            }

            foreach (DayProfile dayProfile in dayProfiles)
            {
                var isValid = true;
                foreach (DayTimeProfile dtp in dayProfile.DayTimeProfiles)
                {
                    if (!tariffIdList.Contains(dtp.TariffNumber))
                    {
                        isValid = false;
                    }
                }
                if (isValid)
                {
                    validDayProfiles.Add(dayProfile.DayId);
                }
            }
            return(validDayProfiles);
        }
コード例 #8
0
        private static string GetPrevalue(ObisId obisId)
        {
            if (obisId.F == 255 || obisId.F == 0)
            {
                return string.Empty;
            }

            return "Vorwert " + obisId.F.ToString();
        }
コード例 #9
0
 private static string GetElectricityTariff(ObisId obisId)
 {
     switch (obisId.E)
     {
         case 0: return "total";
         case 255: return string.Empty;
         default:
             return string.Format("Tarif {0}", obisId.E);
     }
 }
コード例 #10
0
        private static string GetElectricityMeasurand(ObisId obisId)
        {
            switch (obisId.C)
            {
                case 1: return "Σ Wirkleistung+";
                case 2: return "Σ Wirkleistung-";
                case 3: return "Σ Blindleistung+";
                case 4: return "Σ Blindleistung-";
                case 5: return "Σ Blindleistung Q I";
                case 6: return "Σ Blindleistung Q II";
                case 7: return "Σ Blindleistung Q III";
                case 8: return "Σ Blindleistung+ IV";
                case 9: return "Σ Scheinleistung+";
                case 10: return "Σ Scheinleistung-";
                case 13: return "Leistungsfaktor";
                case 14: return "Frequenz";

                case 21: return "L1 Wirkleistung+";
                case 22: return "L1 Wirkleistung-";
                case 23: return "L1 Blindleistung+";
                case 24: return "L1 Blindleistung-";
                case 25: return "L1 Blindleistung Q I";
                case 26: return "L1 Blindleistung Q II";
                case 27: return "L1 Blindleistung Q III";
                case 28: return "L1 Blindleistung+ IV";
                case 29: return "L1 Scheinleistung+";
                case 30: return "L1 Scheinleistung-";
                case 31: return "L1 Strom";
                case 32: return "L1 Spannung";
                case 33: return "L1 Leistungsfaktor";

                case 41: return "L2 Wirkleistung+";
                case 42: return "L2 Wirkleistung-";
                case 43: return "L2 Blindleistung+";
                case 44: return "L2 Blindleistung-";
                case 45: return "L2 Blindleistung Q I";
                case 46: return "L2 Blindleistung Q II";
                case 47: return "L2 Blindleistung Q III";
                case 48: return "L2 Blindleistung+ IV";
                case 49: return "L2 Scheinleistung+";
                case 50: return "L2 Scheinleistung-";
                case 51: return "L2 Strom";
                case 52: return "L2 Spannung";
                case 53: return "L2 Leistungsfaktor";

                case 61: return "L3 Wirkleistung+";
                case 62: return "L3 Wirkleistung-";
                case 63: return "L3 Blindleistung+";
                case 64: return "L3 Blindleistung-";
                case 65: return "L3 Blindleistung Q I";
                case 66: return "L3 Blindleistung Q II";
                case 67: return "L3 Blindleistung Q III";
                case 68: return "L3 Blindleistung+ IV";
                case 69: return "L3 Scheinleistung+";
                case 70: return "L3 Scheinleistung-";
                case 71: return "L3 Strom";
                case 72: return "L3 Spannung";
                case 73: return "L3 Leistungsfaktor";
            }

            return string.Empty;
        }
コード例 #11
0
        private static string GetElectricityMeasurementMode(ObisId obisId)
        {
            switch (obisId.D)
            {
                case 1: return "Kumulativ-Minimum 1";
                case 2: return "Kumulativ-Maximum 1";
                case 3: return "Minimum 1";
                case 4: return "Aktueller Mittelwert";
                case 5: return "Letzter Mittelwert";
                case 6: return "Maximum";
                case 7: return "Momentanwert";
                case 8: return "Zeitintegral 1";
                case 9: return "Zeitintegral 2";
                case 10: return "Zeitintegral 3";
                case 11: return "Kumulativ-Minimum 2";
                case 12: return "Kumulativ-Maximum 2";
                case 13: return "Minimum 2";
                case 14: return "Aktueller Mittelwert 2";
                case 15: return "Letzter Mittelwert 2";
                case 16: return "Maximum 2";

                case 21: return "Kumulativ-Minimum 3";
                case 22: return "Kumulativ-Maximum 3";
                case 23: return "Minimum 3";
                case 24: return "Aktueller Mittelwert 3";
                case 25: return "Letzter Mittelwert 3";
                case 26: return "Maximum 3";
                case 29: return "Zeitintegral 5";

                case 55: return "Prüfmittelwert";
                case 58: return "Prüf-Zeitintegral";
            }

            return string.Empty;
        }
コード例 #12
0
        private static string ConvertElectricity(ObisId obisId)
        {
            switch (obisId.C << 8 | obisId.D)
            {
                // ΣLI Active power (abs(QI+QIV)+(abs(QII+QIII))
                case 0x0F07:

                // ΣLI Active power(abs(QI + QIV) - abs(QII + QIII))
                case 0x1007:
                    return "Aktuelle Wirkleistung";
            }

            var measurand = GetElectricityMeasurand(obisId);
            var measurementMode = GetElectricityMeasurementMode(obisId);
            var tariff = GetElectricityTariff(obisId);
            var prevalue = GetPrevalue(obisId);

            if (string.IsNullOrEmpty(measurand))
            {
                return string.Empty;
            }

            if (string.IsNullOrEmpty(tariff) && string.IsNullOrEmpty(measurementMode))
            {
                return measurand;
            }

            if (string.IsNullOrEmpty(tariff))
            {
                return string.Format("{0}, {1}", measurand, measurementMode);
            }

            if (string.IsNullOrEmpty(measurementMode))
            {
                return string.Format("{0} ({1})", measurand, tariff);
            }

            return string.Format("{0}, {1} ({2})", measurand, measurementMode, tariff);
        }
コード例 #13
0
        private static string ConvertHeat(ObisId obisId)
        {
            string label = string.Empty;

            switch (obisId.C << 8 | obisId.D)
            {
                case 0x0100:
                    label = "Energie (Zählerstand)";
                    break;

                case 0x0200:
                    label = "Volumen (Zählerstand)";
                    break;

                case 0x0800:
                    label = "Leistung";
                    break;

                case 0x0900:
                    label = "Durchfluss";
                    break;

                case 0x0A00:
                    label = "Temperatur";
                    break;

                case 0x0B00:
                    label = "Temperatur (Rücklauf)";
                    break;
            }

            var preValue = GetPrevalue(obisId);
            if (string.IsNullOrEmpty(preValue))
            {
                return label;
            }

            return label + ", " + preValue;
        }
コード例 #14
0
 public void Add(MeasuringRange range, ObisId obisId)
 {
     this.measuringRanges.Add(range);
     this.summaryRegister.First(r => r.TariffId == range.TariffId && obisId.C == r.ObisCode.C).Amount =
         this.summaryRegister.First(r => r.TariffId == range.TariffId && obisId.C == r.ObisCode.C).Amount + range.Amount;
 }
コード例 #15
0
        public void TestGetValidDayProfilesForMeterReading()
        {
            var dayTimeProfiles1 = new List <DayTimeProfile>();
            var dayTimeProfiles2 = new List <DayTimeProfile>();
            var dayTimeProfiles3 = new List <DayTimeProfile>();
            var dayTimeProfiles4 = new List <DayTimeProfile>();

            var hours   = 0;
            var minutes = new int[] { 0, 15, 30, 45 };

            // Initialize dayTimeProfiles1 (just one tariff for the whole day)
            for (int i = 0; i < 96; i++)
            {
                var index = i % (minutes.Length);
                var dtp   = new DayTimeProfile()
                {
                    TariffNumber = 1,

                    StartTime = new TimeVarType()
                    {
                        Hour = (byte)hours, Minute = (byte)minutes[index]
                    }
                };

                hours = index == 3 ? hours + 1 : hours;
                dayTimeProfiles1.Add(dtp);
            }

            // Initialize dayTimeProfiles2 (tariff 2 from 0 to 6; tariff 1 from 6 to 21; tariff 2 from 21 to 0)
            hours = 0;
            for (int i = 0; i < 96; i++)
            {
                var index = i % (minutes.Length);
                var dtp   = new DayTimeProfile()
                {
                    StartTime = new TimeVarType()
                    {
                        Hour = (byte)hours, Minute = (byte)minutes[index]
                    }
                };

                if (hours > 5 && hours < 21)
                {
                    dtp.TariffNumber = 1;
                }
                else
                {
                    dtp.TariffNumber = 2;
                }

                hours = index == 3 ? hours + 1 : hours;
                dayTimeProfiles2.Add(dtp);
            }

            // Initialize dayTimeProfiles3 (tariff 3 from 0 to 12; tariff 4 from 12 to 0)
            hours = 0;
            for (int i = 0; i < 96; i++)
            {
                var index = i % (minutes.Length);
                var dtp   = new DayTimeProfile()
                {
                    StartTime = new TimeVarType()
                    {
                        Hour = (byte)hours, Minute = (byte)minutes[index]
                    }
                };

                if (hours < 12)
                {
                    dtp.TariffNumber = 3;
                }
                else
                {
                    dtp.TariffNumber = 4;
                }

                hours = index == 3 ? hours + 1 : hours;
                dayTimeProfiles3.Add(dtp);
            }

            // Initialize dayTimeProfiles4 (tariff 1 from 0 to 12; tariff 4 from 12 to 0)
            hours = 0;
            for (int i = 0; i < 96; i++)
            {
                var index = i % (minutes.Length);
                var dtp   = new DayTimeProfile()
                {
                    StartTime = new TimeVarType()
                    {
                        Hour = (byte)hours, Minute = (byte)minutes[index]
                    }
                };

                if (hours < 12)
                {
                    dtp.TariffNumber = 1;
                }
                else
                {
                    dtp.TariffNumber = 4;
                }

                hours = index == 3 ? hours + 1 : hours;
                dayTimeProfiles4.Add(dtp);
            }


            // The MeterReading ObisIds
            var oc1 = new ObisId("0100010800FF");
            var oc2 = new ObisId("0100020800FF");

            // Create the list of DayProfiles
            var dayProfiles = new List <DayProfile>();

            var dp1 = new DayProfile()
            {
                DayId = 1, DayTimeProfiles = dayTimeProfiles1
            };
            var dp2 = new DayProfile()
            {
                DayId = 2, DayTimeProfiles = dayTimeProfiles2
            };
            var dp3 = new DayProfile()
            {
                DayId = 3, DayTimeProfiles = dayTimeProfiles3
            };

            dayProfiles.Add(dp1);
            dayProfiles.Add(dp2);
            dayProfiles.Add(dp3);

            var tariffStages = new List <TariffStage>();

            var obisId181 = "0100010801FF";
            var obisId182 = "0100010802FF";
            var obisId281 = "0100020801FF";
            var obisId282 = "0100020802FF";

            var tariffStage1 = new TariffStage()
            {
                Description = "T1", ObisCode = obisId181, TariffNumber = 1
            };
            var tariffStage2 = new TariffStage()
            {
                Description = "T2", ObisCode = obisId182, TariffNumber = 2
            };
            var tariffStage3 = new TariffStage()
            {
                Description = "T3", ObisCode = obisId281, TariffNumber = 3
            };
            var tariffStage4 = new TariffStage()
            {
                Description = "T4", ObisCode = obisId282, TariffNumber = 4
            };

            tariffStages.Add(tariffStage1);
            tariffStages.Add(tariffStage2);
            tariffStages.Add(tariffStage3);
            tariffStages.Add(tariffStage4);

            var target = dayProfiles.GetValidDayProfilesForMeterReading(oc1, tariffStages);

            Assert.AreEqual(2, target.Count);
            Assert.AreEqual((ushort)1, target[0]);
            Assert.AreEqual((ushort)2, target[1]);

            target = dayProfiles.GetValidDayProfilesForMeterReading(oc2, tariffStages);

            Assert.AreEqual(1, target.Count);
            Assert.AreEqual((ushort)3, target[0]);

            var obisId381 = "0100030801FF";
            var obisId482 = "0100040802FF";

            var tariffStage5 = new TariffStage()
            {
                Description = "T5", ObisCode = obisId381, TariffNumber = 5
            };
            var tariffStage6 = new TariffStage()
            {
                Description = "T6", ObisCode = obisId482, TariffNumber = 6
            };

            var tariffStages2 = new List <TariffStage>();

            tariffStages2.Add(tariffStage5);
            tariffStages2.Add(tariffStage6);

            target = dayProfiles.GetValidDayProfilesForMeterReading(oc1, tariffStages2);

            Assert.AreEqual(0, target.Count);

            target = dayProfiles.GetValidDayProfilesForMeterReading(oc2, tariffStages2);

            Assert.AreEqual(0, target.Count);

            var dayProfiles2 = new List <DayProfile>();

            var dp4 = new DayProfile()
            {
                DayId = 4, DayTimeProfiles = dayTimeProfiles4
            };

            dayProfiles2.Add(dp4);

            target = dayProfiles2.GetValidDayProfilesForMeterReading(oc1, tariffStages);

            Assert.AreEqual(0, target.Count);

            target = dayProfiles2.GetValidDayProfilesForMeterReading(oc2, tariffStages);

            Assert.AreEqual(0, target.Count);

            target = dayProfiles2.GetValidDayProfilesForMeterReading(oc1, tariffStages2);

            Assert.AreEqual(0, target.Count);

            target = dayProfiles2.GetValidDayProfilesForMeterReading(oc2, tariffStages2);

            Assert.AreEqual(0, target.Count);

            Assert.ThrowsException <ArgumentNullException>(() => dayProfiles.GetValidDayProfilesForMeterReading(null, null));

            Assert.ThrowsException <ArgumentNullException>(() => dayProfiles.GetValidDayProfilesForMeterReading(null, tariffStages));

            Assert.ThrowsException <ArgumentNullException>(() => dayProfiles.GetValidDayProfilesForMeterReading(oc1, null));

            Assert.ThrowsException <ArgumentException>(() => dayProfiles.GetValidDayProfilesForMeterReading(oc1, new List <TariffStage>()));

            var dayProfilesEmpty = new List <DayProfile>();

            Assert.ThrowsException <ArgumentException>(() => dayProfilesEmpty.GetValidDayProfilesForMeterReading(oc1, tariffStages));
        }
コード例 #16
0
        private static string ConvertGas(ObisId obisId)
        {
            string label = string.Empty;

            switch (obisId.C << 8 | obisId.D)
            {
                case 0x0300:
                    label = "Betriebsvolumen+ (Zählerstand)";
                    break;

                case 0x0315:
                    label = "Betriebsvolumen+ (Zählerstandsdifferenz)";
                    break;

                case 0x0301:
                    label = "Betriebsvolumen+ temperaturkompensiert (Zählerstand)";
                    break;

                case 0x0316:
                    label = "Betriebsvolumen+ temperaturkompensiert (Zählerstandsdifferenz)";
                    break;

                case 0x0302:
                    label = "Normvolumen+ gemessen (Zählerstand)";
                    break;

                case 0x0317:
                    label = "Normvolumen+ gemessen (Zählerstandsdifferenz)";
                    break;

                case 0x0D02:
                    label = "Normvolumen+ umgewertet (Zählerstand)";
                    break;

                case 0x0D15:
                    label = "Normvolumen+ umgewertet (Zählerstandsdifferenz)";
                    break;

                case 0x0600:
                    label = "Betriebsvolumen- (Zählerstand)";
                    break;

                case 0x0615:
                    label = "Betriebsvolumen- (Zählerstandsdifferenz)";
                    break;

                case 0x0601:
                    label = "Betriebsvolumen- temperaturkompensiert (Zählerstand)";
                    break;

                case 0x0616:
                    label = "Betriebsvolumen- temperaturkompensiert (Zählerstandsdifferenz)";
                    break;

                case 0x0602:
                    label = "Normvolumen- gemessen (Zählerstand)";
                    break;

                case 0x0617:
                    label = "Normvolumen- gemessen (Zählerstandsdifferenz)";
                    break;

                case 0x1002:
                    label = "Normvolumen- umgewertet (Zählerstand)";
                    break;

                case 0x1015:
                    label = "Normvolumen- umgewertet (Zählerstandsdifferenz)";
                    break;

                case 0x2B0F:
                    label = "Durchfluss";
                    break;

                case 0x2B10:
                    label = "Durchfluss temperaturkompensiert";
                    break;

                case 0x2B11:
                    label = "Durchfluss gemessen";
                    break;

                case 0x2902:
                    label = "Temperatur";
                    break;

                case 0x2A02:
                    label = "Druck";
                    break;
            }

            var preValue = GetPrevalue(obisId);
            if (string.IsNullOrEmpty(preValue))
            {
                return label;
            }

            return label + ", " + preValue;
        }
コード例 #17
0
 /// <summary>
 /// Formats the specified OBIS without the F component.
 /// </summary>
 /// <param name="obisId">The OBIS to format</param>
 /// <returns>The formatted OBIS id.</returns>
 public static string ToReadableString(this ObisId obisId)
 {
     return($"{obisId.A}-{obisId.B}:{obisId.C}.{obisId.D}.{obisId.E}");
 }
コード例 #18
0
        /// <summary>
        /// Adds the get profile request.
        /// </summary>
        /// <param name="reqFile">The req file.</param>
        /// <param name="obisId">The obis id.</param>
        private void AddGetProfileRequest(SmlFile reqFile, ObisId obisId)
        {
            var msg = new Core.Sml.Messages.Message()
            {
                TransactionId = new[] { (byte)(reqFile.Count + 1) },
                GroupNo = 0x00,
                GetProfileListRequest = new Core.Sml.Messages.GetProfileListRequest()
                {
                    TreePath = new List<Core.Obis.ObisId>()
                    {
                        Core.Obis.ObisId.Parse(ObisUtil.GetBytes(obisId))
                    }
                }
            };

            //var paramTreePath = new SmlTreePath(obisId);
            //var msg = SmlMessageFactory.GetProfileListReq(paramTreePath);

            //var transactionId = new byte[] { (byte)(reqFile.Count + 1) };
            //msg.TransactionId = new SmlOctetstring(transactionId);
            //msg.GroupNo = 0x00;
            reqFile.Add(msg);
        }
コード例 #19
0
ファイル: Taf2Data.cs プロジェクト: flobecker/trudi-koala
 public Taf2Data(ObisId obisID)
 {
     this.ObisID = obisID;
     this.Data   = new List <(DateTime timestamp, int tariff, int value)>();
 }