Created class for dealing with unknown HAN port of Kaifa meter

This commit is contained in:
Roar Fredriksen 2017-09-19 23:09:38 +02:00
parent d48d4493a2
commit 8df007689d
5 changed files with 9678 additions and 0 deletions

View File

@ -44,6 +44,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Crc16.cs" />
<Compile Include="KaifaHanBeta.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Reader.cs" />

View File

@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HanDebugger
{
// As it seems Kaifa/Valider put some premature firmware on my AMS,
// there's need for some dirty hacks to get any information
public class KaifaHanBeta
{
public const byte ListUnknown = 0x00;
public const byte List1 = 0x01;
public const byte List2 = 0x0D;
public const byte List3 = 0x12;
public static byte GetPackageID(byte[] package, int start, int length)
{
switch (package[start + 23])
{
case List1:
case List2:
case List3:
return package[start + 23];
default:
return 0x00;
}
}
public static double GetPackageTime(byte[] package, int start, int length)
{
const int timeStart = 10;
int year = package[start + timeStart] << 8 |
package[start + timeStart + 1];
int month = package[start + timeStart + 2];
int day = package[start + timeStart + 3];
int hour = package[start + timeStart + 5];
int minute = package[start + timeStart + 6];
int second = package[start + timeStart + 7];
return new DateTime(year, month, day, hour, minute, second).Subtract(new DateTime(1970, 1, 1, 0, 0, 0, 0)).TotalSeconds;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -52,6 +52,7 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="DlmsReaderTest.cs" />
<Compile Include="ReaderTest.cs" />
<Compile Include="KaifaHanBetaTest.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
@ -63,6 +64,9 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Content Include="ESP 20170918 Raw.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="SampleData.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>

View File

@ -0,0 +1,49 @@
using System;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.IO;
using System.Collections.Generic;
using HanDebugger;
namespace HanDebuggerTest
{
[TestClass]
[DeploymentItem(@"ESP 20170918 Raw.txt")]
[DeploymentItem("Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll")]
public class KaifaHanBetaTest
{
[TestMethod]
public void TestGetPackageID()
{
Dictionary<byte, int> packageCount = new Dictionary<byte, int>();
var packages = File.ReadAllLines("ESP 20170918 Raw.txt");
var lines = packages.Select(line => line.Trim().Split(' ').Select(v => (byte)int.Parse(v, System.Globalization.NumberStyles.HexNumber)).ToArray()).ToArray();
foreach (var line in lines)
{
byte list = KaifaHanBeta.GetPackageID(line, 0, line.Length);
if (packageCount.ContainsKey(list))
packageCount[list]++;
else
packageCount.Add(list, 1);
}
var startTime = new DateTime(1970, 1, 1, 0, 0, 0, 0).AddSeconds(KaifaHanBeta.GetPackageTime(lines[0], 0, lines[0].Length));
var finishTime = new DateTime(1970, 1, 1, 0, 0, 0, 0).AddSeconds(KaifaHanBeta.GetPackageTime(lines[packages.Length - 1], 0, packages[packages.Length - 1].Length));
var durationInSeconds = finishTime.Subtract(startTime).TotalSeconds;
Assert.IsTrue(durationInSeconds > 60 * 60 * 4, $"There should be more than 4 hours of recording. Was: {durationInSeconds / 60 * 60 * 4}");
double list3PerSecond = (1.0 / 3600.0);
double list2PerSecond = (1.0 / 10.0) - list3PerSecond;
double list1PerSecond = (1.0 / 2.0) - list2PerSecond;
Assert.AreEqual(false, packageCount.ContainsKey(KaifaHanBeta.ListUnknown), "There should be no unknown packages");
Assert.AreEqual(durationInSeconds * list1PerSecond, packageCount[KaifaHanBeta.List1], 1 + 0.01 * packageCount[KaifaHanBeta.List1], "There should be one 'List1' every 2.5s");
Assert.AreEqual(durationInSeconds * list2PerSecond, packageCount[KaifaHanBeta.List2], 1 + 0.01 * packageCount[KaifaHanBeta.List2], "There should be one 'List2' every 10s");
Assert.AreEqual(durationInSeconds * list3PerSecond, packageCount[KaifaHanBeta.List3], 1 + 0.01 * packageCount[KaifaHanBeta.List3], "There should be one 'List3' every 1h");
double targetList1To2Ratio = 4.0;
double actualList1To2Ratio = (double)packageCount[KaifaHanBeta.List1] / (double)packageCount[KaifaHanBeta.List2];
Assert.AreEqual(targetList1To2Ratio, actualList1To2Ratio, 0.01, "There should be a ratio of List1:List2 of 4");
}
}
}