diff --git a/DSMRParser.Tests/DSMRParser.Tests.csproj b/DSMRParser.Tests/DSMRParser.Tests.csproj
index 5c97bb2..a27e292 100644
--- a/DSMRParser.Tests/DSMRParser.Tests.csproj
+++ b/DSMRParser.Tests/DSMRParser.Tests.csproj
@@ -24,22 +24,24 @@
-
-
- PreserveNewest
-
-
- PreserveNewest
-
-
- PreserveNewest
-
-
- PreserveNewest
-
-
- PreserveNewest
-
-
-
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
diff --git a/DSMRParser.Tests/TelegramParserTests.cs b/DSMRParser.Tests/TelegramParserTests.cs
index 2d3f50e..8819f57 100644
--- a/DSMRParser.Tests/TelegramParserTests.cs
+++ b/DSMRParser.Tests/TelegramParserTests.cs
@@ -242,4 +242,63 @@ public void DSMRTelegramParser_Reads_V5_Telegrams()
Assert.AreEqual(11223.322m, telegram.SlaveDelivered!.Value!.Value);
Assert.AreEqual(OBISUnit.kWh, telegram.SlaveDelivered!.Value!.Unit);
}
+
+ [TestMethod]
+ public void DSMRTelegramParser_Reads_V5_0_2_Flu_Telegrams()
+ {
+ var target = new DSMRTelegramParser();
+ var telegram = target.Parse(File.ReadAllBytes(@"testdata\v5_02_flu_ok.txt"));
+ Assert.AreEqual(@"FLU5\253770234_A", telegram.Identification);
+ Assert.AreEqual(50217, telegram.DSMRVersion);
+ Assert.AreEqual("K8EG004046395507", telegram.EquipmentId);
+ Assert.AreEqual(new DateTimeOffset(2023, 01, 8, 22, 29, 30, TimeSpan.FromHours(1)), telegram.TimeStamp);
+
+ Assert.AreEqual(3540.994m, telegram.EnergyDeliveredTariff1!.Value);
+ Assert.AreEqual(OBISUnit.kWh, telegram.EnergyDeliveredTariff1!.Unit);
+ Assert.AreEqual(4343.832m, telegram.EnergyDeliveredTariff2!.Value);
+ Assert.AreEqual(OBISUnit.kWh, telegram.EnergyDeliveredTariff2!.Unit);
+ Assert.AreEqual(447.900m, telegram.EnergyReturnedTariff1!.Value);
+ Assert.AreEqual(OBISUnit.kWh, telegram.EnergyReturnedTariff1!.Unit);
+ Assert.AreEqual(203.828m, telegram.EnergyReturnedTariff2!.Value);
+ Assert.AreEqual(OBISUnit.kWh, telegram.EnergyReturnedTariff2!.Unit);
+
+ Assert.AreEqual(2, telegram.ElectricityTariff);
+
+ Assert.AreEqual(OBISUnit.kW, telegram.PowerDeliveredCurrentAvg!.Unit);
+ Assert.AreEqual(0.554m, telegram.PowerDeliveredCurrentAvg!.Value);
+
+ Assert.AreEqual(new DateTimeOffset(2023, 01, 7, 17, 15, 00, TimeSpan.FromHours(1)), telegram.EnergyDeliveredMaxRunningMonth!.DateTime);
+ Assert.AreEqual(OBISUnit.kW, telegram.EnergyDeliveredMaxRunningMonth!.Value!.Unit);
+ Assert.AreEqual(2.572m, telegram.EnergyDeliveredMaxRunningMonth!.Value!.Value);
+
+ // TODO: Maximum demand – Active energy import of the last 13 months
+
+ Assert.AreEqual(0.544m, telegram.PowerDelivered!.Value);
+ Assert.AreEqual(OBISUnit.kW, telegram.PowerDelivered!.Unit);
+ Assert.AreEqual(0.0m, telegram.PowerReturned!.Value);
+ Assert.AreEqual(OBISUnit.kW, telegram.PowerDelivered!.Unit);
+
+ Assert.AreEqual(0.544m, telegram.PowerDeliveredL1!.Value);
+ Assert.AreEqual(OBISUnit.kW, telegram.PowerDeliveredL1!.Unit);
+ Assert.AreEqual(0.0m, telegram.PowerReturnedL1!.Value);
+ Assert.AreEqual(OBISUnit.kW, telegram.PowerReturnedL1!.Unit);
+
+ Assert.AreEqual(231.5m, telegram.VoltageL1!.Value);
+ Assert.AreEqual(OBISUnit.V, telegram.VoltageL1!.Unit);
+
+ Assert.AreEqual(2.85m, telegram.CurrentL1!.Value);
+ Assert.AreEqual(OBISUnit.A, telegram.CurrentL1!.Unit);
+
+ // TODO: add breaker state
+ // TODO: add limiter threshold
+ // TODO: add Fuse supervision threshold
+
+ Assert.AreEqual(string.Empty, telegram.MessageLong);
+ Assert.AreEqual(3, telegram.GasDeviceType);
+ Assert.AreEqual("9999ABCD123456789", telegram.GasEquipmentId);
+ Assert.AreEqual(1, telegram.GasValvePosition);
+ Assert.AreEqual(new DateTimeOffset(2023, 01, 8, 22, 25, 01, TimeSpan.FromHours(1)), telegram.GasDelivered!.DateTime!.Value);
+ Assert.AreEqual(4856.664m, telegram.GasDelivered!.Value!.Value);
+ Assert.AreEqual(OBISUnit.m3, telegram.GasDelivered!.Value!.Unit);
+ }
}
\ No newline at end of file
diff --git a/DSMRParser.Tests/testdata/v5_02_flu_ok.txt b/DSMRParser.Tests/testdata/v5_02_flu_ok.txt
new file mode 100644
index 0000000..8943d2e
--- /dev/null
+++ b/DSMRParser.Tests/testdata/v5_02_flu_ok.txt
@@ -0,0 +1,28 @@
+/FLU5\253770234_A
+
+0-0:96.1.4(50217)
+0-0:96.1.1(4B384547303034303436333935353037)
+0-0:1.0.0(230108222930W)
+1-0:1.8.1(003540.994*kWh)
+1-0:1.8.2(004343.832*kWh)
+1-0:2.8.1(000447.900*kWh)
+1-0:2.8.2(000203.828*kWh)
+0-0:96.14.0(0002)
+1-0:1.4.0(00.554*kW)
+1-0:1.6.0(230107171500W)(02.572*kW)
+0-0:98.1.0(1)(1-0:1.6.0)(1-0:1.6.0)(230101000000W)(221229143000W)(04.875*kW)
+1-0:1.7.0(00.544*kW)
+1-0:2.7.0(00.000*kW)
+1-0:21.7.0(00.544*kW)
+1-0:22.7.0(00.000*kW)
+1-0:32.7.0(231.5*V)
+1-0:31.7.0(002.85*A)
+0-0:96.3.10(1)
+0-0:17.0.0(999.9*kW)
+1-0:31.4.0(999*A)
+0-0:96.13.0()
+0-1:24.1.0(003)
+0-1:96.1.1(3939393941424344313233343536373839)
+0-1:24.4.0(1)
+0-1:24.2.3(230108222501W)(04856.664*m3)
+!7450
diff --git a/DSMRParser/BelgianOBISRegistry.cs b/DSMRParser/BelgianOBISRegistry.cs
new file mode 100644
index 0000000..de434cf
--- /dev/null
+++ b/DSMRParser/BelgianOBISRegistry.cs
@@ -0,0 +1,20 @@
+using DSMRParser.Models;
+
+namespace DSMRParser;
+
+///
+/// OBIS registry of known s found in belgian DSMR s.
+///
+public static class BelgianOBISRegistry
+{
+ /// The version of the DSMR telegram.
+ public static readonly OBISDescriptor DSMRVersion = new() { Id = new OBISId(0, 0, 96, 1, 4), Description = "DSMR version" };
+ /// Gas equipment identifier.
+ public static readonly OBISDescriptor GasEquipmentId = new() { Id = new OBISId(0, 1, 96, 1, 1), Description = "Gas equipment id" };
+ /// Gas delivered.
+ public static readonly OBISDescriptor GasDelivered = new() { Id = new OBISId(0, 1, 24, 2, 3), Description = "Gas delivered", Unit = OBISUnit.m3 };
+ /// Peak power current month.
+ public static readonly OBISDescriptor PowerMaxCurrentAverage = new() { Id = new OBISId(1, 0, 1, 4, 0), Description = "Current average demand - active energy import", Unit = OBISUnit.kW };
+ /// Peak power current month.
+ public static readonly OBISDescriptor PowerDeliveredMaxRunningMonth = new() { Id = new OBISId(1, 0, 1, 6, 0), Description = "Peak power running Month", Unit = OBISUnit.kW};
+}
\ No newline at end of file
diff --git a/DSMRParser/Models/Telegram.cs b/DSMRParser/Models/Telegram.cs
index cfd3aad..0ff8613 100644
--- a/DSMRParser/Models/Telegram.cs
+++ b/DSMRParser/Models/Telegram.cs
@@ -35,7 +35,7 @@ public class Telegram(string? identification, IEnumerable<(OBISId obisid, IEnume
/// Gets the identification of the DSMR meter the telegram originated from.
public string? Identification { get; init; } = identification ?? throw new ArgumentNullException(nameof(identification));
/// Gets the version of the DSMR telegram.
- public int? DSMRVersion => ParseInt(OBISRegistry.DSMRVersion);
+ public int? DSMRVersion => ParseInt(OBISRegistry.DSMRVersion) ?? ParseInt(BelgianOBISRegistry.DSMRVersion);
/// Gets the timestamp of the DSMR telegram.
public DateTimeOffset? TimeStamp => ParseTimeStamp(OBISRegistry.TimeStamp);
/// Equipment identifier.
@@ -48,10 +48,14 @@ public class Telegram(string? identification, IEnumerable<(OBISId obisid, IEnume
public UnitValue? EnergyReturnedTariff1 => ParseDecimalUnit(OBISRegistry.EnergyReturnedTariff1);
/// Electricity returned (Tariff 2).
public UnitValue? EnergyReturnedTariff2 => ParseDecimalUnit(OBISRegistry.EnergyReturnedTariff2);
+ /// Instantaneous energy delivered max running month.
+ public TimeStampedValue>? EnergyDeliveredMaxRunningMonth => ParseTimeStampedValues(BelgianOBISRegistry.PowerDeliveredMaxRunningMonth, ParseDecimalUnit).FirstOrDefault();
/// Tariff indicator electricity.
public int? ElectricityTariff => ParseInt(OBISRegistry.ElectricityTariff);
/// Actual electricity power delivered.
public UnitValue? PowerDelivered => ParseDecimalUnit(OBISRegistry.PowerDelivered);
+ /// Actual electricity power delivered average.
+ public UnitValue? PowerDeliveredCurrentAvg => ParseDecimalUnit(BelgianOBISRegistry.PowerMaxCurrentAverage);
/// Actual electricity power returned.
public UnitValue? PowerReturned => ParseDecimalUnit(OBISRegistry.PowerReturned);
/// The actual threshold Electricity.
@@ -87,11 +91,11 @@ public class Telegram(string? identification, IEnumerable<(OBISId obisid, IEnume
/// Instantaneous voltage L3.
public UnitValue? VoltageL3 => ParseDecimalUnit(OBISRegistry.VoltageL3);
/// Instantaneous current L1.
- public UnitValue? CurrentL1 => ParseIntUnit(OBISRegistry.CurrentL1);
+ public UnitValue? CurrentL1 => ParseDecimalUnit(OBISRegistry.CurrentL1);
/// Instantaneous current L2.
- public UnitValue? CurrentL2 => ParseIntUnit(OBISRegistry.CurrentL2);
+ public UnitValue? CurrentL2 => ParseDecimalUnit(OBISRegistry.CurrentL2);
/// Instantaneous current L3.
- public UnitValue? CurrentL3 => ParseIntUnit(OBISRegistry.CurrentL3);
+ public UnitValue? CurrentL3 => ParseDecimalUnit(OBISRegistry.CurrentL3);
/// Instantaneous active power L1.
public UnitValue? PowerDeliveredL1 => ParseDecimalUnit(OBISRegistry.PowerDeliveredL1);
/// Instantaneous active power L2.
@@ -107,12 +111,14 @@ public class Telegram(string? identification, IEnumerable<(OBISId obisid, IEnume
/// Gas devicetype.
public int? GasDeviceType => ParseInt(OBISRegistry.GasDeviceType);
/// Gas equipment identifier.
- public string? GasEquipmentId => DecodeString(GetByDescriptor(OBISRegistry.GasEquipmentId));
+ public string? GasEquipmentId => DecodeString(GetByDescriptor(OBISRegistry.GasEquipmentId)) ?? DecodeString(GetByDescriptor(BelgianOBISRegistry.GasEquipmentId));
/// Gas valve position.
public int? GasValvePosition => ParseInt(OBISRegistry.GasValvePosition);
+
/// Gas delivered.
public TimeStampedValue>? GasDelivered =>
- ParseTimeStampedValues(OBISRegistry.GasDelivered, ParseDecimalUnit).FirstOrDefault();
+ ParseTimeStampedValues(OBISRegistry.GasDelivered, ParseDecimalUnit).FirstOrDefault() ??
+ ParseTimeStampedValues(BelgianOBISRegistry.GasDelivered, ParseDecimalUnit).FirstOrDefault();
/// Gas delivered - OLD (pre-V4).
public TimeStampedValue>? GasDeliveredOld =>