Mssl.Ebt.Models
1.5.0
dotnet add package Mssl.Ebt.Models --version 1.5.0
NuGet\Install-Package Mssl.Ebt.Models -Version 1.5.0
<PackageReference Include="Mssl.Ebt.Models" Version="1.5.0" />
<PackageVersion Include="Mssl.Ebt.Models" Version="1.5.0" />
<PackageReference Include="Mssl.Ebt.Models" />
paket add Mssl.Ebt.Models --version 1.5.0
#r "nuget: Mssl.Ebt.Models, 1.5.0"
#:package Mssl.Ebt.Models@1.5.0
#addin nuget:?package=Mssl.Ebt.Models&version=1.5.0
#tool nuget:?package=Mssl.Ebt.Models&version=1.5.0
MSSL EBT System Data Message Model and Interface Definitions
Data models of transmission messages and interface definitions of files and reports used by the Electronic Business Transaction (EBT) system of the Market Support Services Licensee (MSSL) for Open Electricity Market (OEM) retailers in Singapore.
All data models and interface definitions in this package are based on the Market Participant User Manual and Secured File Transfer Protocol Kit found in the Resources: Becoming a Licensed Electricity Retailer page of the Open Electricity Market website.
📦 Installation
Install the package via the NuGet Package Manager Console, the Nuget Package Manager UI, the .NET CLI or by adding a package reference.
.NET CLI
dotnet add package Mssl.Ebt.Models.x.x.x.nupkg
Package Manager
Install-Package Mssl.Ebt.Models.x.x.x.nupkg
🛠️ Usage
The majority of the strongly typed classes under the Mssl.Ebt.Models.Messages namespace in this package participate in the XML serialisation/deserialisation of transaction messages received from or submitted to the EBT system.
Transaction Messages
Consider an incoming "Validation Acknowledgement" message received from the EBT system:
<?xml version="1.0" encoding="UTF-8"?>
<ValidationAcknowledgement>
<TransactionId>930000XXXX:168XXX</TransactionId>
<Result>pass</Result>
</ValidationAcknowledgement>
The message can be deserialised into a ValidationAcknowledgement object:
XmlSerializer xmlSerializer = new XmlSerializer(typeof(ValidationAcknowledgement));
using (StreamReader reader = new StreamReader("Validation Acknowledgement.xml"))
{
ValidationAcknowledgement validationAcknowledgement = xmlSerializer.Deserialize(reader) as ValidationAcknowledgement;
}
Data File Interface Definitions
The contents of a data file received from the EBT system can be in either XML or CSV format, indicated by the value of the ContentFormat element of the XML message.
A data file can also be of a significant size and hence may be compressed using the ZIP standard. A compressed data file is indicated by the value Y in the Compressed element of the XML message.
The compressed data takes the form of a string encoded with the Base64 Content-Transfer-Encoding algorithm and saved as CDATA in the Data element.
Consider the following XML message in a file SRLP Usage Data.xml. The message contains a CSV-formatted data file in compressed form:
<DispatchData>
<TransactionId>0673XXXX</TransactionId>
<ContentFormat>CSV</ContentFormat>
<Compressed>Y</Compressed>
<Data>
<![CDATA[UEsDBBQACAgIAMxpkVkAAAAAAAAAAAAAAAAEAAAAZGF0YX3UvU0DQRCA0RyJHlzACe/8+HxL7MSB
y3ADlvsXCAmBkXnJBvvdJU87c7ner7fd+fS+G2PEOrdtvr6MdR+5z15iGW+f99/nMn61RCu0Rjug
rWhHtA1tosVQlEyIJmQTwgnphHhCPiGgkFBKKPl2JJQSSgmlhFJCKaGUUEqoJFQSKo6XhEpCJaGS
...
...
...
NTeQhFpCLaGWUD8R+gBQSwcI01Cg9AkBAAD4CgAAUEsBAhQAFAAICAgAzGmRWdNQoPQJAQAA+AoA
AAQAAAAAAAAAAAAAAAAAAAAAAGRhdGFQSwUGAAAAAAEAAQAyAAAAOwEAAAAA]]>
</Data>
</DispatchData>
To obtain the data, the Base64 encoded string is first decoded as a ZIP file and then the CSV data file extracted:
XmlSerializer xmlSerializer = new XmlSerializer(typeof(DispatchData));
using (StreamReader reader = new StreamReader("SRLP Usage Data.xml"))
{
// deserialize the XML message into a DispatchData object
DispatchData dispatchData = xmlSerializer.Deserialize(reader) as DispatchData;
try
{
if (dispatchData.Compressed == Mssl.Ebt.Models.Messages.YesNo.Yes)
{
// decode & deflate the compressed data
string base64String = string.Join(Environment.NewLine, dispatchData.Data);
File.WriteAllBytes("srlp-usage-data.zip", Convert.FromBase64String(base64String));
ZipArchive zipArchive = ZipFile.OpenRead("srlp-usage-data.zip");
Dictionary<string, string> dataFiles = zipArchive.Entries
.ToDictionary(f => f.Name, f => Path.Combine(Directory.GetCurrentDirectory(), f.Name));
foreach (KeyValuePair<string, string> dataFile in dataFiles)
{
// extract each file from the zip archive to the current working directory
string localFile = $"{dataFile.Value}.{dispatchData.ContentFormat.ToString().ToLower()}";
zipArchive.Entries.First(f => f.Name.Equals(dataFile.Key, StringComparison.OrdinalIgnoreCase))
.ExtractToFile(localFile, true);
// read the extracted file and process the data
FileHelpersEngine<SrlpUsageData> engine = new FileHelpersEngine<SrlpUsageData>();
List<SrlpUsageData> srlpUsageDataList = engine.ReadFromFile(localFile);
...
...
}
}
}
catch
{
...
}
finally
{
...
}
}
CSV File Entries Modelled As Interfaces
Each of the following interfaces under the Mssl.Ebt.Models.Messages.DataFiles namespace represents a detail line in the respective CSV file:
IAmiUsageData: Advanced Metering Infrastructure (AMI) Usage Data file or MDA Adjusted AMI Usage Data file.IConsumerHistoryData: Consumer History Data file.IMarketCompanyUsageData: Market Company Usage data file.IMdaAdjustedUsageAccount: MDA-adjusted usage account.ISrlpUsageData: Static Residential Load Profile (SRLP) Usage Data file or MDA Adjusted SRLP Usage Data file.
Each interface defines the base structure of the CSV data, allowing itself to be implemented by a class set up to work with a file-processing library (e.g. CsvHelper, FileHelpers) to read and write CSV data.
For example, the following is an implementation of the ISrlpUsageData interface by a class that is set up to work with the FileHelpers library:
using FileHelpers;
using Mssl.Ebt.Models.Messages.DataFiles;
using MyNamespace.Converters; // definition of custom converter DecimalValueConverter
/// <summary>
/// Represents an entry in the Static Residential Load Profile (SRLP) Usage Data or MDA Adjusted SRLP Usage Data file.
/// </summary>
[DelimitedRecord(",")]
internal class SrlpUsageData : ISrlpUsageData
{
#region Object properties.
/// <summary>
/// The date of reading for this entry in <c>dd/MM/yy</c> format.
/// </summary>
[FieldConverter(ConverterKind.Date, "dd/MM/yy")]
public DateTime RecordDate { get; set; }
/// <summary>
/// The half-hourly interval number (1 to 48).
/// </summary>
[FieldConverter(ConverterKind.Byte)]
public byte Interval { get; set; }
/// <summary>
/// Consising of 10 digits and 7 decimals, this is the Active value for a SRLP Usage Data,
/// or the MDA Active (MDA Adjusted) for a MDA Adjusted SRLP Usage Data.
/// </summary>
[FieldConverter(typeof(DecimalValueConverter), 7)]
public decimal ActiveValue { get; set; }
/// <summary>
/// Consising of 10 digits and 7 decimals, this is the Adjusted Active value for a SRLP Usage Data,
/// or the TLF Adjusted Active (MDA Adjusted) for a MDA Adjusted SRLP Usage Data.
/// </summary>
[FieldConverter(typeof(DecimalValueConverter), 7)]
public decimal AdjustedActiveValue { get; set; }
#endregion
#region Constructors.
/// <summary>
/// Creates a new instance of the <see cref="SrlpUsageData"/> class.
/// </summary>
public SrlpUsageData()
{
this.RecordDate = default(DateTime);
this.Interval = default(byte);
this.ActiveValue = default(decimal);
this.AdjustedActiveValue = default(decimal);
}
#endregion
}
The FileHelpersEngine<SrlpUsageData> object then reads the CSV file and returns a collection of SrlpUsageData objects (List<SrlpUsageData>), shown in the earlier example.
CSV File Sections
Each of the following classes represents a CSV section (a group of delimited entries) in its respective data file:
AmiMeterUsageData: Advanced Metering Infrastructure (AMI) usage data or MDA adjusted AMI usage data for a single metering point.ConsumerMeterHistoryData: Consumer History Data file.SrlpMeterUsageData: Static Residential Load Profile (SRLP) usage data or MDA adjusted SRLP usage data for a single metering point.
🚀 Target Frameworks
- .NET: Core 3.0, Core 3.1, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0
- .NET Framework: 3.5, 4.0, 4.5, 4.5.2, 4.6.1, 4.6.2, 4.7.2, 4.8, 4.8.1
- .NET Standard: 2.0, 2.1
👨💻 Author and Contact
- Maintainer: Jonathan Bong
- E-mail: jonbong1607@hotmail.com
📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 is compatible. net5.0-windows was computed. net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 is compatible. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 is compatible. netcoreapp3.1 is compatible. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 is compatible. |
| .NET Framework | net35 is compatible. net40 is compatible. net403 was computed. net45 is compatible. net451 was computed. net452 is compatible. net46 was computed. net461 is compatible. net462 is compatible. net463 was computed. net47 was computed. net471 was computed. net472 is compatible. net48 is compatible. net481 is compatible. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETCoreApp 3.0
- No dependencies.
-
.NETCoreApp 3.1
- No dependencies.
-
.NETFramework 3.5
- No dependencies.
-
.NETFramework 4.0
- No dependencies.
-
.NETFramework 4.5
- No dependencies.
-
.NETFramework 4.5.2
- No dependencies.
-
.NETFramework 4.6.1
- No dependencies.
-
.NETFramework 4.6.2
- No dependencies.
-
.NETFramework 4.7.2
- No dependencies.
-
.NETFramework 4.8
- No dependencies.
-
.NETFramework 4.8.1
- No dependencies.
-
.NETStandard 2.0
- No dependencies.
-
.NETStandard 2.1
- No dependencies.
-
net10.0
- No dependencies.
-
net5.0
- No dependencies.
-
net6.0
- No dependencies.
-
net7.0
- No dependencies.
-
net8.0
- No dependencies.
-
net9.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Changes in v1.5.0 (2026-08-25):
- [Added] Billing Period Change classes as defined in "SFTP Reports File Structure v2.8" dated 29 July 2026.