Merge pull request #2 from roarfred/implementing_kamstrup

Implementing kamstrup
This commit is contained in:
Roar Fredriksen
2017-10-24 22:42:33 +02:00
committed by GitHub
22 changed files with 841 additions and 239 deletions

2
.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
.vs/
[Dd]ebug/

Binary file not shown.

View File

@@ -0,0 +1,15 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26730.16
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HanReader", "HanReader.vcxitems", "{CD0F5364-923B-49E4-8BE5-EA7D8A60DF80}"
EndProject
Global
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {AFFB18CF-A4FB-46A9-8148-C5B4A380C48B}
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="Globals">
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
<HasSharedItems>true</HasSharedItems>
<ItemsProjectGuid>{cd0f5364-923b-49e4-8be5-ea7d8a60df80}</ItemsProjectGuid>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory)</AdditionalIncludeDirectories>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ProjectCapability Include="SourceItemsFromImports" />
</ItemGroup>
<ItemGroup>
<Text Include="$(MSBuildThisFileDirectory)keywords.txt" />
<Text Include="$(MSBuildThisFileDirectory)readme.txt" />
<Text Include="$(MSBuildThisFileDirectory)library.properties" />
</ItemGroup>
<ItemGroup>
<!-- <ClInclude Include="$(MSBuildThisFileDirectory)HanReader.h" /> -->
<ClInclude Include="$(MSBuildThisFileDirectory)src\Crc16.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)src\DlmsReader.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)src\HanReader.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)src\Kaifa.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)src\Kamstrup.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="$(MSBuildThisFileDirectory)src\Crc16.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)src\DlmsReader.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)src\HanReader.cpp" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;s</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="C:\Users\roarf\OneDrive\Documents\GitHub\AmsToMqttBridge\Code\Arduino\HanReader\src\Crc16.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="C:\Users\roarf\OneDrive\Documents\GitHub\AmsToMqttBridge\Code\Arduino\HanReader\src\DlmsReader.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="C:\Users\roarf\OneDrive\Documents\GitHub\AmsToMqttBridge\Code\Arduino\HanReader\src\HanReader.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Text Include="$(MSBuildThisFileDirectory)readme.txt" />
<Text Include="$(MSBuildThisFileDirectory)library.properties" />
<Text Include="$(MSBuildThisFileDirectory)keywords.txt" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="C:\Users\roarf\OneDrive\Documents\GitHub\AmsToMqttBridge\Code\Arduino\HanReader\src\Crc16.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="C:\Users\roarf\OneDrive\Documents\GitHub\AmsToMqttBridge\Code\Arduino\HanReader\src\DlmsReader.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="C:\Users\roarf\OneDrive\Documents\GitHub\AmsToMqttBridge\Code\Arduino\HanReader\src\HanReader.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="C:\Users\roarf\OneDrive\Documents\GitHub\AmsToMqttBridge\Code\Arduino\HanReader\src\Kaifa.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="C:\Users\roarf\OneDrive\Documents\GitHub\AmsToMqttBridge\Code\Arduino\HanReader\src\Kamstrup.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,19 @@
Arduino Compatible Cross Platform C++ Library Project : For more information see http://www.visualmicro.com
This project works exactly the same way as an Arduino library.
Add this project to any solution that contains an Arduino project and #include <headers.h> in code as you would any normal Arduino library headers.
To enable intellisense and to support live build discovery outside of the "standard" Arduino library locations, ensure that the library is added as a shared project reference to the master Arduino project. To do this, right click the master project "References" node and then click "Add Reference". A window will open and the library will appear on the "Shared Projects" tab. Click the checkbox next to the library name to add the reference. If this library is moved the shared referencemust be removed and re-added.
VS2017 has a bug, workround: After moving existing source code within a "library or shared project", close and re-open the solution.
Visual Studio will display intellisense for libraries based on the platform/board that has been specified for the currently active "Startup Project" of the current solution.
IMPORTANT: The arduino.cc Library Rules must be followed when adding code or restructing libraries.
blog: http://www.visualmicro.com/post/2017/01/16/Arduino-Cross-Platform-Library-Development.aspx

View File

@@ -5,60 +5,201 @@ HanReader::HanReader()
}
void HanReader::setup(HardwareSerial *hanPort, unsigned long baudrate, SerialConfig config, Stream *debugPort)
{
// Initialize H/W serial port for MBus communication
if (hanPort != NULL)
{
hanPort->begin(baudrate, config);
while (!hanPort) {}
}
han = hanPort;
bytesRead = 0;
debug = debugPort;
if (debug) debug->println("MBUS serial setup complete");
}
void HanReader::setup(HardwareSerial *hanPort)
{
// Initialize H/W serial port for MBus communication
hanPort->begin(2400, SERIAL_8E1);
while (!hanPort) {}
bytesRead = 0;
han = hanPort;
setup(hanPort, 2400, SERIAL_8E1, NULL);
}
void HanReader::setup(HardwareSerial *hanPort, Stream *debugPort)
{
setup(hanPort);
debug = debugPort;
if (debug) debug->println("MBUS serial setup complete");
setup(hanPort, 2400, SERIAL_8E1, debugPort);
}
bool HanReader::read(byte data)
{
if (reader.Read(data))
{
bytesRead = reader.GetRawData(buffer, 0, 512);
list = getInt(1, buffer, 0, bytesRead);
return true;
}
}
bool HanReader::read()
{
if (han->available())
{
byte newByte = han->read();
if (reader.Read(newByte))
{
bytesRead = reader.GetRawData(buffer, 0, 512);
list = (List)kaifa.GetListID(buffer, 0, bytesRead);
return true;
}
}
return false;
if (han->available())
{
byte newByte = han->read();
return read(newByte);
}
return false;
}
List HanReader::getList()
int HanReader::getList()
{
return list;
}
time_t HanReader::getPackageTime()
{
return kaifa.GetPackageTime(buffer, 0, bytesRead);
return getTime(0);
}
time_t HanReader::getTime(int objectId)
{
return getTime(objectId, buffer, 0, bytesRead);
}
int HanReader::getInt(List1_ObisObjects objectId) { return getInt((int)objectId); }
int HanReader::getInt(List2_ObisObjects objectId) { return getInt((int)objectId); }
int HanReader::getInt(List3_ObisObjects objectId) { return getInt((int)objectId); }
int HanReader::getInt(int objectId)
{
return kaifa.GetInt(objectId, buffer, 0, bytesRead);
return getInt(objectId, buffer, 0, bytesRead);
}
String HanReader::getString(List1_ObisObjects objectId) { return getString((int)objectId); }
String HanReader::getString(List2_ObisObjects objectId) { return getString((int)objectId); }
String HanReader::getString(List3_ObisObjects objectId) { return getString((int)objectId); }
String HanReader::getString(int objectId)
{
return kaifa.GetString(objectId, buffer, 0, bytesRead);
return getString(objectId, buffer, 0, bytesRead);
}
int HanReader::findValuePosition(int dataPosition, byte *buffer, int start, int length)
{
for (int i = start + dataHeader; i<length; i++)
{
if (dataPosition-- == 0)
return i;
else if (buffer[i] == 0x0A) // OBIS code value
i += buffer[i + 1] + 1;
else if (buffer[i] == 0x09) // string value
i += buffer[i + 1] + 1;
else if (buffer[i] == 0x02) // byte value (1 byte)
i += 1;
else if (buffer[i] == 0x12) // integer value (2 bytes)
i += 2;
else if (buffer[i] == 0x06) // integer value (4 bytes)
i += 4;
else
{
if (debug)
{
debug->print("Unknown data type found: 0x");
debug->println(buffer[i], HEX);
}
return 0; // unknown data type found
}
}
if (debug)
{
debug->print("Passed the end of the data. Length was: ");
debug->println(length);
}
return 0;
}
time_t HanReader::getTime(int dataPosition, byte *buffer, int start, int length)
{
// TODO: check if the time is represented always as a 12 byte string (0x09 0x0C)
int timeStart = findValuePosition(dataPosition, buffer, start, length);
timeStart += 2;
int year = buffer[start + timeStart] << 8 |
buffer[start + timeStart + 1];
int month = buffer[start + timeStart + 2];
int day = buffer[start + timeStart + 3];
int hour = buffer[start + timeStart + 5];
int minute = buffer[start + timeStart + 6];
int second = buffer[start + timeStart + 7];
return toUnixTime(year, month, day, hour, minute, second);
}
int HanReader::getInt(int dataPosition, byte *buffer, int start, int length)
{
int valuePosition = findValuePosition(dataPosition, buffer, start, length);
if (valuePosition > 0)
{
int value = 0;
int bytes = 0;
switch (buffer[valuePosition++])
{
case 0x12:
bytes = 2;
break;
case 0x06:
bytes = 4;
break;
case 0x02:
bytes = 1;
break;
}
for (int i = valuePosition; i < valuePosition + bytes; i++)
{
value = value << 8 | buffer[i];
}
return value;
}
return 0;
}
String HanReader::getString(int dataPosition, byte *buffer, int start, int length)
{
int valuePosition = findValuePosition(dataPosition, buffer, start, length);
if (valuePosition > 0)
{
String value = String("");
for (int i = valuePosition + 2; i < valuePosition + buffer[valuePosition + 1] + 2; i++)
{
value += String((char)buffer[i]);
}
return value;
}
return String("");
}
time_t HanReader::toUnixTime(int year, int month, int day, int hour, int minute, int second)
{
byte daysInMonth[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
long secondsPerMinute = 60;
long secondsPerHour = secondsPerMinute * 60;
long secondsPerDay = secondsPerHour * 24;
long time = (year - 1970) * secondsPerDay * 365L;
for (int yearCounter = 1970; yearCounter<year; yearCounter++)
if ((yearCounter % 4 == 0) && ((yearCounter % 100 != 0) || (yearCounter % 400 == 0)))
time += secondsPerDay;
if (month > 2 && (year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0)))
time += secondsPerDay;
for (int monthCounter = 1; monthCounter<month; monthCounter++)
time += daysInMonth[monthCounter - 1] * secondsPerDay;
time += (day - 1) * secondsPerDay;
time += hour * secondsPerHour;
time += minute * secondsPerMinute;
time += second;
return (time_t)time;
}

View File

@@ -8,36 +8,41 @@
#endif
#include "KaifaHan.h"
#include "DlmsReader.h"
class HanReader
{
public:
HanReader();
void setup(HardwareSerial *hanPort);
void setup(HardwareSerial *hanPort, Stream *debugPort);
bool read();
List getList();
time_t getPackageTime();
int getInt(List1_ObisObjects objectId);
int getInt(List2_ObisObjects objectId);
int getInt(List3_ObisObjects objectId);
int getInt(int objectId);
String getString(List1_ObisObjects objectId);
String getString(List2_ObisObjects objectId);
String getString(List3_ObisObjects objectId);
String getString(int objectId);
public:
const uint dataHeader = 8;
private:
Stream *debug;
HardwareSerial *han;
byte buffer[512];
int bytesRead;
KaifaHan kaifa;
DlmsReader reader;
List list;
HanReader();
void setup(HardwareSerial *hanPort);
void setup(HardwareSerial *hanPort, Stream *debugPort);
void setup(HardwareSerial *hanPort, unsigned long baudrate, SerialConfig config, Stream *debugPort);
bool read();
bool read(byte data);
int getList();
time_t getPackageTime();
int getInt(int objectId);
String getString(int objectId);
time_t getTime(int objectId);
private:
Stream *debug;
HardwareSerial *han;
byte buffer[512];
int bytesRead;
DlmsReader reader;
int list;
int findValuePosition(int dataPosition, byte *buffer, int start, int length);
long getTime(int dataPosition, byte *buffer, int start, int length);
int getInt(int dataPosition, byte *buffer, int start, int length);
String getString(int dataPosition, byte *buffer, int start, int length);
time_t toUnixTime(int year, int month, int day, int hour, int minute, int second);
};

View File

@@ -0,0 +1,55 @@
#ifndef _KAIFA_h
#define _KAIFA_h
enum class Kaifa : byte {
List1 = 0x01,
List2 = 0x0D,
List3 = 0x12
};
enum class Kaifa_List1_ObisObjects {
ActivePowerImported
};
enum class Kaifa_List2_ObisObjects {
Time,
ListID,
ObisListVersionIdentifier,
MeterID,
MeterType,
ActivePowerImported,
ActivePowerExported,
ReactivePowerImported,
ReactivePowerExported,
CurrentPhaseL1,
CurrentPhaseL2,
CurrentPhaseL3,
VoltagePhaseL1,
VoltagePhaseL2,
VoltagePhaseL3
};
enum class Kaifa_List3_ObisObjects {
Time,
ListID,
ObisListVersionIdentifier,
MeterID,
MeterType,
ActivePowerImported,
ActivePowerExported,
ReactivePowerImported,
ReactivePowerExported,
CurrentPhaseL1,
CurrentPhaseL2,
CurrentPhaseL3,
VoltagePhaseL1,
VoltagePhaseL2,
VoltagePhaseL3,
ClockAndDate,
TotalActiveEnergyImported,
TotalActiveEnergyExported,
TotalReactiveEnergyImported,
TotalReactiveEnergyExported
};
#endif

View File

@@ -1,104 +0,0 @@
#include "KaifaHan.h"
byte KaifaHan::GetListID(byte *buffer, int start, int length)
{
if (length > 23)
{
byte list = buffer[start + 23];
if (list == (byte)List::List1) return (byte)List::List1;
if (list == (byte)List::List2) return (byte)List::List2;
if (list == (byte)List::List3) return (byte)List::List3;
}
return (byte)List::ListUnknown;
}
long KaifaHan::GetPackageTime(byte *buffer, int start, int length)
{
const int timeStart = 10;
int year = buffer[start + timeStart] << 8 |
buffer[start + timeStart + 1];
int month = buffer[start + timeStart + 2];
int day = buffer[start + timeStart + 3];
int hour = buffer[start + timeStart + 5];
int minute = buffer[start + timeStart + 6];
int second = buffer[start + timeStart + 7];
return toUnixTime(year, month, day, hour, minute, second);
}
int KaifaHan::GetInt(int dataPosition, byte *buffer, int start, int length)
{
int valuePosition = findValuePosition(dataPosition, buffer, start, length);
if (valuePosition > 0)
{
int value = 0;
for (int i = valuePosition + 1; i < valuePosition + 5; i++)
{
value = value << 8 | buffer[i];
}
return value;
}
return 0;
}
int KaifaHan::findValuePosition(int dataPosition, byte *buffer, int start, int length)
{
const int dataStart = 24;
for (int i=start + dataStart; i<length; i++)
{
if (dataPosition-- == 0)
return i;
else if (buffer[i] == 0x09) // string value
i += buffer[i+1] + 1;
else if (buffer[i] == 0x06) // integer value
i += 4;
else
return 0; // unknown data type found
}
return 0;
}
String KaifaHan::GetString(int dataPosition, byte *buffer, int start, int length)
{
int valuePosition = findValuePosition(dataPosition, buffer, start, length);
if (valuePosition > 0)
{
String value = String("");
for (int i = valuePosition + 2; i < valuePosition + buffer[valuePosition + 1]; i++)
{
value += String((char)buffer[i]);
}
return value;
}
return String("");
}
time_t KaifaHan::toUnixTime(int year, int month, int day, int hour, int minute, int second)
{
byte daysInMonth[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
long secondsPerMinute = 60;
long secondsPerHour = secondsPerMinute * 60;
long secondsPerDay = secondsPerHour * 24;
long time = (year - 1970) * secondsPerDay * 365L;
for (int yearCounter = 1970; yearCounter<year; yearCounter++)
if ((yearCounter % 4 == 0) && ((yearCounter % 100 != 0) || (yearCounter % 400 == 0)))
time += secondsPerDay;
if (month > 2 && (year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0)))
time += secondsPerDay;
for (int monthCounter = 1; monthCounter<month; monthCounter++)
time += daysInMonth[monthCounter - 1] * secondsPerDay;
time += (day - 1) * secondsPerDay;
time += hour * secondsPerHour;
time += minute * secondsPerMinute;
time += second;
return (time_t)time;
}

View File

@@ -1,73 +0,0 @@
#ifndef _KAIFAHAN_h
#define _KAIFAHAN_h
#if defined(ARDUINO) && ARDUINO >= 100
#include "arduino.h"
#else
#include "WProgram.h"
#endif
class KaifaHan
{
public:
byte GetListID(byte *buffer, int start, int length);
long GetPackageTime(byte *buffer, int start, int length);
int GetInt(int dataPosition, byte *buffer, int start, int length);
String GetString(int dataPosition, byte *buffer, int start, int length);
protected:
private:
int findValuePosition(int dataPosition, byte *buffer, int start, int length);
time_t toUnixTime(int year, int month, int day, int hour, int minute, int second);
};
enum class List : byte {
ListUnknown = 0x00,
List1 = 0x01,
List2 = 0x0D,
List3 = 0x12
};
enum class List1_ObisObjects {
ActivePowerImported
};
enum class List2_ObisObjects {
ObisListVersionIdentifier,
MeterID,
MeterType,
ActivePowerImported,
ActivePowerExported,
ReactivePowerImported,
ReactivePowerExported,
CurrentPhaseL1,
CurrentPhaseL2,
CurrentPhaseL3,
VoltagePhaseL1,
VoltagePhaseL2,
VoltagePhaseL3
};
enum class List3_ObisObjects {
ObisListVersionIdentifier,
MeterID,
MeterType,
ActivePowerImported,
ActivePowerExported,
ReactivePowerImported,
ReactivePowerExported,
CurrentPhaseL1,
CurrentPhaseL2,
CurrentPhaseL3,
VoltagePhaseL1,
VoltagePhaseL2,
VoltagePhaseL3,
ClockAndDate,
TotalActiveEnergyImported,
TotalActiveEnergyExported,
TotalReactiveEnergyImported,
TotalReactiveEnergyExported
};
#endif

View File

@@ -0,0 +1,45 @@
// Kamstrup.h
#ifndef _KAMSTRUP_h
#define _KAMSTRUP_h
enum class Kamstrup
{
List1 = 0x19
};
enum class Kamstrup_List1
{
Kamstrup_List1_Time,
Kamstrup_List1_ListID,
Kamstrup_List1_ListVersionIdentifier,
Kamstrup_List1_MeterID_OBIS,
Kamstrup_List1_MeterID,
Kamstrup_List1_MeterType_OBIS,
Kamstrup_List1_MeterType,
Kamstrup_List1_ActivePowerPos_OBIS,
Kamstrup_List1_ActivePowerPos,
Kamstrup_List1_ActivePowerNeg_OBIS,
Kamstrup_List1_ActivePowerNeg,
Kamstrup_List1_ReactivePowerPos_OBIS,
Kamstrup_List1_ReactivePowerPos,
Kamstrup_List1_ReactivePowerNeg_OBIS,
Kamstrup_List1_ReactivePowerNeg,
Kamstrup_List1_CurrentL1_OBIS,
Kamstrup_List1_CurrentL1,
Kamstrup_List1_CurrentL2_OBIS,
Kamstrup_List1_CurrentL2,
Kamstrup_List1_CurrentL3_OBIS,
Kamstrup_List1_CurrentL3,
Kamstrup_List1_VoltageL1_OBIS,
Kamstrup_List1_VoltageL1,
Kamstrup_List1_VoltageL2_OBIS,
Kamstrup_List1_VoltageL2,
Kamstrup_List1_VoltageL3_OBIS,
Kamstrup_List1_VoltageL3
};
#endif

View File

@@ -0,0 +1,110 @@
/*
* Simple sketch to simulate reading data from a Kamstrup
* AMS Meter.
*
* Created 24. October 2017 by Roar Fredriksen
*/
#include <HanReader.h>
#include <Kamstrup.h>
// The HAN Port reader
HanReader hanReader;
byte samples[] =
// [2017-10-20 04.43.32.368 - Received 229 (0xE5) bytes]
{
0x7E, 0xA0, 0xE3, 0x2B, 0x21, 0x13, 0x98, 0x86, 0xE6, 0xE7, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00,
0x09, 0x0C, 0x07, 0xE1, 0x0A, 0x14, 0x05, 0x03, 0x2B, 0x1E, 0xFF, 0x80, 0x00, 0x00, 0x02, 0x19,
0x0A, 0x0E, 0x4B, 0x61, 0x6D, 0x73, 0x74, 0x72, 0x75, 0x70, 0x5F, 0x56, 0x30, 0x30, 0x30, 0x31,
0x09, 0x06, 0x01, 0x01, 0x00, 0x00, 0x05, 0xFF, 0x0A, 0x10, 0x35, 0x37, 0x30, 0x36, 0x35, 0x36,
0x37, 0x32, 0x37, 0x34, 0x33, 0x38, 0x39, 0x37, 0x30, 0x32, 0x09, 0x06, 0x01, 0x01, 0x60, 0x01,
0x01, 0xFF, 0x0A, 0x12, 0x36, 0x38, 0x34, 0x31, 0x31, 0x32, 0x31, 0x42, 0x4E, 0x32, 0x34, 0x33,
0x31, 0x30, 0x31, 0x30, 0x34, 0x30, 0x09, 0x06, 0x01, 0x01, 0x01, 0x07, 0x00, 0xFF, 0x06, 0x00,
0x00, 0x05, 0xBC, 0x09, 0x06, 0x01, 0x01, 0x02, 0x07, 0x00, 0xFF, 0x06, 0x00, 0x00, 0x00, 0x00,
0x09, 0x06, 0x01, 0x01, 0x03, 0x07, 0x00, 0xFF, 0x06, 0x00, 0x00, 0x00, 0x00, 0x09, 0x06, 0x01,
0x01, 0x04, 0x07, 0x00, 0xFF, 0x06, 0x00, 0x00, 0x01, 0xCE, 0x09, 0x06, 0x01, 0x01, 0x1F, 0x07,
0x00, 0xFF, 0x06, 0x00, 0x00, 0x02, 0x34, 0x09, 0x06, 0x01, 0x01, 0x33, 0x07, 0x00, 0xFF, 0x06,
0x00, 0x00, 0x00, 0xCA, 0x09, 0x06, 0x01, 0x01, 0x47, 0x07, 0x00, 0xFF, 0x06, 0x00, 0x00, 0x01,
0xFF, 0x09, 0x06, 0x01, 0x01, 0x20, 0x07, 0x00, 0xFF, 0x12, 0x00, 0xE8, 0x09, 0x06, 0x01, 0x01,
0x34, 0x07, 0x00, 0xFF, 0x12, 0x00, 0xE4, 0x09, 0x06, 0x01, 0x01, 0x48, 0x07, 0x00, 0xFF, 0x12,
0x00, 0xE9, 0xA1, 0xA5, 0x7E
};
int sampleIndex = 0;
void setup() {
setupDebugPort();
// initialize the HanReader
// (passing no han port, as we are feeding data manually, but provide Serial for debugging)
hanReader.setup(NULL, &Serial);
}
void setupDebugPort()
{
// Initialize the Serial port for debugging
Serial.begin(115200);
while (!Serial) {}
Serial.setDebugOutput(true);
Serial.println("Serial1");
Serial.println("Serial debugging port initialized");
}
void loop() {
// Read one byte from the "port", and see if we got a full package
if (hanReader.read(samples[sampleIndex++]))
{
// Get the list identifier
int list = hanReader.getList();
Serial.println("");
Serial.print("List #");
Serial.print((byte)list, HEX);
Serial.print(": ");
// Only care for the ACtive Power Imported, which is found in the first list
if (list == (int)Kamstrup::List1)
{
String id = hanReader.getString((int)Kamstrup_List1::Kamstrup_List1_ListVersionIdentifier);
Serial.println(id);
time_t time = hanReader.getPackageTime();
Serial.print("Time of the package is: ");
Serial.println(time);
int power = hanReader.getInt((int)Kamstrup_List1::Kamstrup_List1_ActivePowerPos);
Serial.print("Power consumtion is right now: ");
Serial.print(power);
Serial.println(" W");
float current[3];
current[0] = (float)hanReader.getInt((int)Kamstrup_List1::Kamstrup_List1_CurrentL1) / 100.0;
current[1] = (float)hanReader.getInt((int)Kamstrup_List1::Kamstrup_List1_CurrentL2) / 100.0;
current[2] = (float)hanReader.getInt((int)Kamstrup_List1::Kamstrup_List1_CurrentL3) / 100.0;
int voltage[3];
voltage[0] = hanReader.getInt((int)Kamstrup_List1::Kamstrup_List1_VoltageL1);
voltage[1] = hanReader.getInt((int)Kamstrup_List1::Kamstrup_List1_VoltageL2);
voltage[2] = hanReader.getInt((int)Kamstrup_List1::Kamstrup_List1_VoltageL3);
for (int i = 0; i < 3; i++)
{
Serial.print("L");
Serial.print(i + 1);
Serial.print(" is ");
Serial.print(voltage[i]);
Serial.print(" V (");
Serial.print(current[i]);
Serial.println(" A)");
}
}
}
delay(10);
if (sampleIndex >= sizeof(samples))
{
delay(2000);
sampleIndex = 0;
}
}

View File

@@ -0,0 +1,31 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26730.16
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KamstrupTest", "KamstrupTest.vcxproj", "{C5F80730-F44F-4478-BDAE-6634EFC2CA88}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HanReader", "..\HanReader\HanReader.vcxitems", "{CD0F5364-923B-49E4-8BE5-EA7D8A60DF80}"
EndProject
Global
GlobalSection(SharedMSBuildProjectFiles) = preSolution
..\HanReader\HanReader.vcxitems*{c5f80730-f44f-4478-bdae-6634efc2ca88}*SharedItemsImports = 4
..\HanReader\HanReader.vcxitems*{cd0f5364-923b-49e4-8be5-ea7d8a60df80}*SharedItemsImports = 9
EndGlobalSection
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x86 = Debug|x86
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{C5F80730-F44F-4478-BDAE-6634EFC2CA88}.Debug|x86.ActiveCfg = Debug|Win32
{C5F80730-F44F-4478-BDAE-6634EFC2CA88}.Debug|x86.Build.0 = Debug|Win32
{C5F80730-F44F-4478-BDAE-6634EFC2CA88}.Release|x86.ActiveCfg = Release|Win32
{C5F80730-F44F-4478-BDAE-6634EFC2CA88}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {852F88D2-3495-4048-9662-E3DDE77A7FD7}
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,99 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{C5F80730-F44F-4478-BDAE-6634EFC2CA88}</ProjectGuid>
<RootNamespace>
</RootNamespace>
<ProjectName>KamstrupTest</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>
</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>
</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
<Import Project="..\HanReader\HanReader.vcxitems" Label="Shared" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(ProjectDir)..\KamstrupTest;$(ProjectDir)..\HanReader\src;$(ProjectDir)..\..\..\..\..\..\..\..\..\Program Files (x86)\Arduino\libraries;$(ProjectDir)..\..\..\..\..\..\..\AppData\Local\arduino15\packages\esp8266\hardware\esp8266\2.3.0\libraries;$(ProjectDir)..\..\..\..\..\..\..\Google Drive\Private\Elektronikk\Arduino\libraries;$(ProjectDir)..\..\..\..\..\..\..\AppData\Local\arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266;$(ProjectDir)..\..\..\..\..\..\..\AppData\Local\arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266\libb64;$(ProjectDir)..\..\..\..\..\..\..\AppData\Local\arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266\spiffs;$(ProjectDir)..\..\..\..\..\..\..\AppData\Local\arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266\umm_malloc;$(ProjectDir)..\..\..\..\..\..\..\AppData\Local\arduino15\packages\esp8266\hardware\esp8266\2.3.0\variants\generic;$(ProjectDir)..\..\..\..\..\..\..\AppData\Local\arduino15\packages\esp8266\hardware\esp8266\2.3.0\tools\sdk\include;$(ProjectDir)..\..\..\..\..\..\..\AppData\Local\arduino15\packages\esp8266\hardware\esp8266\2.3.0\tools\sdk\lwip\include;$(ProjectDir)..\..\..\..\..\..\..\AppData\Local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\1.20.0-26-gb404fb9-2\xtensa-lx106-elf\include\c++\4.8.2;$(ProjectDir)..\..\..\..\..\..\..\AppData\Local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\1.20.0-26-gb404fb9-2\xtensa-lx106-elf\include\c++\4.8.2\xtensa-lx106-elf;$(ProjectDir)..\..\..\..\..\..\..\AppData\Local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\1.20.0-26-gb404fb9-2\xtensa-lx106-elf\include;$(ProjectDir)..\..\..\..\..\..\..\AppData\Local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\1.20.0-26-gb404fb9-2\lib\gcc\xtensa-lx106-elf\4.8.2\include;$(ProjectDir)..\..\..\..\..\..\..\AppData\Local\arduino15\packages\esp8266\hardware\esp8266\2.3.0\tools\sdk\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<ForcedIncludeFiles>$(ProjectDir)__vm\.KamstrupTest.vsarduino.h;%(ForcedIncludeFiles)</ForcedIncludeFiles>
<IgnoreStandardIncludePath>false</IgnoreStandardIncludePath>
<PreprocessorDefinitions>__ESP8266_ESp8266__;__ESP8266_ESP8266__;__ets__;ICACHE_FLASH;F_CPU=80000000L;LWIP_OPEN_SRC;ARDUINO=106012;ARDUINO_ESP8266_ESP01;ARDUINO_ARCH_ESP8266;ESP8266;__cplusplus=201103L;_VMICRO_INTELLISENSE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ProjectCapability Include="VisualMicro" />
</ItemGroup>
<ItemGroup>
<None Include="KamstrupTest.ino">
<FileType>CppCode</FileType>
</None>
</ItemGroup>
<ItemGroup>
<ClInclude Include="__vm\.KamstrupTest.vsarduino.h" />
</ItemGroup>
<PropertyGroup>
<DebuggerFlavor>VisualMicroDebugger</DebuggerFlavor>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
<ProjectExtensions>
<VisualStudio>
<UserProperties custom_esp8266_generic_UploadSpeed="115200" arduino.upload.port="COM3" />
</VisualStudio>
</ProjectExtensions>
</Project>

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<None Include="KamstrupTest.ino" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="__vm\.KamstrupTest.vsarduino.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,112 @@
/*
Editor: http://www.visualmicro.com
visual micro and the arduino ide ignore this code during compilation. this code is automatically maintained by visualmicro, manual changes to this file will be overwritten
the contents of the Visual Micro sketch sub folder can be deleted prior to publishing a project
all non-arduino files created by visual micro and all visual studio project or solution files can be freely deleted and are not required to compile a sketch (do not delete your own code!).
note: debugger breakpoints are stored in '.sln' or '.asln' files, knowledge of last uploaded breakpoints is stored in the upload.vmps.xml file. Both files are required to continue a previous debug session without needing to compile and upload again
Hardware: Generic ESP8266 Module, Platform=esp8266, Package=esp8266
*/
#if defined(_VMICRO_INTELLISENSE)
#ifndef _VSARDUINO_H_
#define _VSARDUINO_H_
#define __ESP8266_ESp8266__
#define __ESP8266_ESP8266__
#define __ets__
#define ICACHE_FLASH
#define F_CPU 80000000L
#define LWIP_OPEN_SRC
#define ARDUINO 106012
#define ARDUINO_ESP8266_ESP01
#define ARDUINO_ARCH_ESP8266
#define ESP8266
#define __cplusplus 201103L
#undef __cplusplus
#define __cplusplus 201103L
#define __STDC__
#define __ARM__
#define __arm__
#define __inline__
#define __asm__(x)
#define __asm__
#define __extension__
#define __ATTR_PURE__
#define __ATTR_CONST__
#define __volatile__
#define __ASM
#define __INLINE
#define __attribute__(noinline)
//#define _STD_BEGIN
//#define EMIT
#define WARNING
#define _Lockit
#define __CLR_OR_THIS_CALL
#define C4005
//
//typedef int uint8_t;
//#define __ARMCC_VERSION 400678
//#define PROGMEM
//#define string_literal
//
//#define prog_void
//#define PGM_VOID_P int
//
typedef int _read;
typedef int _seek;
typedef int _write;
typedef int _close;
typedef int __cleanup;
//#define inline
#define __builtin_clz
#define __builtin_clzl
#define __builtin_clzll
#define __builtin_labs
#define __builtin_va_list
typedef int __gnuc_va_list;
#define __ATOMIC_ACQ_REL
#define __CHAR_BIT__
#define _EXFUN()
typedef unsigned char byte;
extern "C" void __cxa_pure_virtual() {;}
typedef long __INTPTR_TYPE__ ;
typedef long __UINTPTR_TYPE__ ;
typedef long __SIZE_TYPE__ ;
typedef long __PTRDIFF_TYPE__;
#include "new"
#include "Esp.h"
#include <Arduino.h>
#include <common.h>
#include <pins_arduino.h>
#include "..\generic\Common.h"
#include "..\generic\pins_arduino.h"
#undef F
#define F(string_literal) ((const PROGMEM char *)(string_literal))
#undef PSTR
#define PSTR(string_literal) ((const PROGMEM char *)(string_literal))
//current vc++ does not understand this syntax so use older arduino example for intellisense
//todo:move to the new clang/gcc project types.
#define interrupts() sei()
#define noInterrupts() cli()
#include "KamstrupTest.ino"
#endif
#endif

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -5,20 +5,26 @@ HanReader::HanReader()
}
void HanReader::setup(HardwareSerial *hanPort, unsigned long baudrate, SerialConfig config, Stream *debugPort)
{
// Initialize H/W serial port for MBus communication
hanPort->begin(baudrate, config);
while (!hanPort) {}
bytesRead = 0;
han = hanPort;
debug = debugPort;
if (debug) debug->println("MBUS serial setup complete");
}
void HanReader::setup(HardwareSerial *hanPort)
{
// Initialize H/W serial port for MBus communication
hanPort->begin(2400, SERIAL_8E1);
while (!hanPort) {}
bytesRead = 0;
han = hanPort;
setup(hanPort, 2400, SERIAL_8E1, NULL);
}
void HanReader::setup(HardwareSerial *hanPort, Stream *debugPort)
{
setup(hanPort);
debug = debugPort;
if (debug) debug->println("MBUS serial setup complete");
setup(hanPort, 2400, SERIAL_8E1, debugPort);
}
bool HanReader::read()

View File

@@ -18,6 +18,7 @@ class HanReader
HanReader();
void setup(HardwareSerial *hanPort);
void setup(HardwareSerial *hanPort, Stream *debugPort);
void setup(HardwareSerial *hanPort, unsigned long baudrate, SerialConfig config, Stream *debugPort);
bool read();
List getList();
time_t getPackageTime();