From ab175ec9ec2ef96391d0e6698922c68d5a9153f0 Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Sat, 18 Apr 2020 11:04:43 +0200 Subject: [PATCH 1/2] Added correct conversion for int8, int16 and uint32 --- lib/HanReader/src/HanReader.cpp | 82 +++++++++++++++++------ lib/HanReader/src/HanReader.h | 8 ++- src/AmsData.cpp | 114 ++++++++++++++++---------------- src/AmsToMqttBridge.ino | 2 +- 4 files changed, 125 insertions(+), 81 deletions(-) diff --git a/lib/HanReader/src/HanReader.cpp b/lib/HanReader/src/HanReader.cpp index 79617c59..78c5aca4 100644 --- a/lib/HanReader/src/HanReader.cpp +++ b/lib/HanReader/src/HanReader.cpp @@ -100,10 +100,14 @@ time_t HanReader::getTime(int objectId) { return getTime(objectId, buffer, 0, bytesRead); } -int HanReader::getInt(int objectId) { +int32_t HanReader::getInt(int objectId) { return getInt(objectId, buffer, 0, bytesRead); } +uint32_t HanReader::getUint(int objectId) { + return getUint32(objectId, buffer, 0, bytesRead); +} + String HanReader::getString(int objectId) { return getString(objectId, buffer, 0, bytesRead); } @@ -192,36 +196,70 @@ 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 0x10: - bytes = 2; - break; + case 0x01: + case 0x02: + case 0x16: + return getUint8(dataPosition, buffer, start, length); + case 0x0F: + return getInt8(dataPosition, buffer, start, length); case 0x12: - bytes = 2; - break; + return getUint16(dataPosition, buffer, start, length); + case 0x10: + return getInt16(dataPosition, buffer, start, length); case 0x06: - bytes = 4; - break; - case 0x02: - bytes = 1; - break; + return getUint32(dataPosition, buffer, start, length); + } + } + return 0; +} + +int8_t HanReader::getInt8(int dataPosition, byte *buffer, int start, int length) { + int valuePosition = findValuePosition(dataPosition, buffer, start, length); + if (valuePosition > 0 && buffer[valuePosition++] == 0x0F) { + return buffer[valuePosition]; + } + return 0; +} + +int16_t HanReader::getInt16(int dataPosition, byte *buffer, int start, int length) { + int valuePosition = findValuePosition(dataPosition, buffer, start, length); + if (valuePosition > 0 && buffer[valuePosition++] == 0x10) { + return buffer[valuePosition] << 8 | buffer[valuePosition+1]; + } + return 0; +} + +uint8_t HanReader::getUint8(int dataPosition, byte *buffer, int start, int length) { + int valuePosition = findValuePosition(dataPosition, buffer, start, length); + if (valuePosition > 0) { + switch(buffer[valuePosition++]) { case 0x01: - bytes = 1; - break; - case 0x0F: - bytes = 1; - break; + case 0x02: case 0x16: - bytes = 1; - break; + return buffer[valuePosition]; } + } + return 0; +} - for (int i = valuePosition; i < valuePosition + bytes; i++) { +uint16_t HanReader::getUint16(int dataPosition, byte *buffer, int start, int length) { + int valuePosition = findValuePosition(dataPosition, buffer, start, length); + if (valuePosition > 0 && buffer[valuePosition++] == 0x12) { + return buffer[valuePosition] << 8 | buffer[valuePosition+1]; + } + return 0; +} + +uint32_t HanReader::getUint32(int dataPosition, byte *buffer, int start, int length) { + int valuePosition = findValuePosition(dataPosition, buffer, start, length); + if (valuePosition > 0) { + if(buffer[valuePosition++] != 0x06) + return 0; + uint32_t value = 0; + for (int i = valuePosition; i < valuePosition + 4; i++) { value = value << 8 | buffer[i]; } - return value; } return 0; diff --git a/lib/HanReader/src/HanReader.h b/lib/HanReader/src/HanReader.h index 46cea46d..488d5313 100644 --- a/lib/HanReader/src/HanReader.h +++ b/lib/HanReader/src/HanReader.h @@ -25,7 +25,8 @@ class HanReader bool read(byte data); int getListSize(); time_t getPackageTime(); - int getInt(int objectId); + int32_t getInt(int objectId); // Use this for uint8, int8, uint16, int16 + uint32_t getUint(int objectId); // Only for uint32 String getString(int objectId); time_t getTime(int objectId); @@ -43,6 +44,11 @@ class HanReader time_t getTime(int dataPosition, byte *buffer, int start, int length); time_t getTime(byte *buffer, int start, int length); int getInt(int dataPosition, byte *buffer, int start, int length); + int8_t getInt8(int dataPosition, byte *buffer, int start, int length); + uint8_t getUint8(int dataPosition, byte *buffer, int start, int length); + int16_t getInt16(int dataPosition, byte *buffer, int start, int length); + uint16_t getUint16(int dataPosition, byte *buffer, int start, int length); + uint32_t getUint32(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); diff --git a/src/AmsData.cpp b/src/AmsData.cpp index 86589d4e..656995a9 100644 --- a/src/AmsData.cpp +++ b/src/AmsData.cpp @@ -46,42 +46,42 @@ void AmsData::extractFromKaifa(HanReader& hanReader, int listSize) { } else { switch(listSize) { case (int)Kaifa::List3PhaseLong: - meterTimestamp = hanReader.getTime( (int)Kaifa_List3Phase::MeterClock); - activeImportCounter = ((double) hanReader.getInt((int)Kaifa_List3Phase::CumulativeActiveImportEnergy)) / 1000; - activeExportCounter = ((double) hanReader.getInt((int)Kaifa_List3Phase::CumulativeActiveExportEnergy)) / 1000; - reactiveImportCounter = ((double) hanReader.getInt((int)Kaifa_List3Phase::CumulativeReactiveImportEnergy)) / 1000; - reactiveExportCounter = ((double) hanReader.getInt((int)Kaifa_List3Phase::CumulativeReactiveExportEnergy)) / 1000; + meterTimestamp = hanReader.getTime( (int)Kaifa_List3Phase::MeterClock); + activeImportCounter = ((double) hanReader.getUint((int)Kaifa_List3Phase::CumulativeActiveImportEnergy)) / 1000; + activeExportCounter = ((double) hanReader.getUint((int)Kaifa_List3Phase::CumulativeActiveExportEnergy)) / 1000; + reactiveImportCounter = ((double) hanReader.getUint((int)Kaifa_List3Phase::CumulativeReactiveImportEnergy)) / 1000; + reactiveExportCounter = ((double) hanReader.getUint((int)Kaifa_List3Phase::CumulativeReactiveExportEnergy)) / 1000; case (int)Kaifa::List3PhaseShort: - listId = hanReader.getString( (int)Kaifa_List3Phase::ListVersionIdentifier); - meterId = hanReader.getString( (int)Kaifa_List3Phase::MeterID); - meterType = hanReader.getString( (int)Kaifa_List3Phase::MeterType); - activeImportPower = hanReader.getInt( (int)Kaifa_List3Phase::ActiveImportPower); - reactiveImportPower = hanReader.getInt( (int)Kaifa_List3Phase::ReactiveImportPower); - activeExportPower = hanReader.getInt( (int)Kaifa_List3Phase::ActiveExportPower); - reactiveExportPower = hanReader.getInt( (int)Kaifa_List3Phase::ReactiveExportPower); - l1current = ((double) hanReader.getInt((int)Kaifa_List3Phase::CurrentL1)) / 1000; - l2current = ((double) hanReader.getInt((int)Kaifa_List3Phase::CurrentL2)) / 1000; - l3current = ((double) hanReader.getInt((int)Kaifa_List3Phase::CurrentL3)) / 1000; - l1voltage = ((double) hanReader.getInt((int)Kaifa_List3Phase::VoltageL1)) / 10; - l2voltage = ((double) hanReader.getInt((int)Kaifa_List3Phase::VoltageL2)) / 10; - l3voltage = ((double) hanReader.getInt((int)Kaifa_List3Phase::VoltageL3)) / 10; + listId = hanReader.getString( (int)Kaifa_List3Phase::ListVersionIdentifier); + meterId = hanReader.getString( (int)Kaifa_List3Phase::MeterID); + meterType = hanReader.getString( (int)Kaifa_List3Phase::MeterType); + activeImportPower = hanReader.getUint( (int)Kaifa_List3Phase::ActiveImportPower); + reactiveImportPower = hanReader.getUint( (int)Kaifa_List3Phase::ReactiveImportPower); + activeExportPower = hanReader.getUint( (int)Kaifa_List3Phase::ActiveExportPower); + reactiveExportPower = hanReader.getUint( (int)Kaifa_List3Phase::ReactiveExportPower); + l1current = ((double) hanReader.getInt( (int)Kaifa_List3Phase::CurrentL1)) / 1000; + l2current = ((double) hanReader.getInt( (int)Kaifa_List3Phase::CurrentL2)) / 1000; + l3current = ((double) hanReader.getInt( (int)Kaifa_List3Phase::CurrentL3)) / 1000; + l1voltage = ((double) hanReader.getInt( (int)Kaifa_List3Phase::VoltageL1)) / 10; + l2voltage = ((double) hanReader.getInt( (int)Kaifa_List3Phase::VoltageL2)) / 10; + l3voltage = ((double) hanReader.getInt( (int)Kaifa_List3Phase::VoltageL3)) / 10; break; case (int)Kaifa::List1PhaseLong: - meterTimestamp = hanReader.getTime( (int)Kaifa_List1Phase::MeterClock); - activeImportCounter = ((double) hanReader.getInt((int)Kaifa_List1Phase::CumulativeActiveImportEnergy)); - activeExportCounter = ((double) hanReader.getInt((int)Kaifa_List1Phase::CumulativeActiveExportEnergy)); - reactiveImportCounter = ((double) hanReader.getInt((int)Kaifa_List1Phase::CumulativeReactiveImportEnergy)); - reactiveExportCounter = ((double) hanReader.getInt((int)Kaifa_List1Phase::CumulativeReactiveExportEnergy)); + meterTimestamp = hanReader.getTime( (int)Kaifa_List1Phase::MeterClock); + activeImportCounter = ((double) hanReader.getUint((int)Kaifa_List1Phase::CumulativeActiveImportEnergy)); + activeExportCounter = ((double) hanReader.getUint((int)Kaifa_List1Phase::CumulativeActiveExportEnergy)); + reactiveImportCounter = ((double) hanReader.getUint((int)Kaifa_List1Phase::CumulativeReactiveImportEnergy)); + reactiveExportCounter = ((double) hanReader.getUint((int)Kaifa_List1Phase::CumulativeReactiveExportEnergy)); case (int)Kaifa::List1PhaseShort: - listId = hanReader.getString( (int)Kaifa_List1Phase::ListVersionIdentifier); - meterId = hanReader.getString( (int)Kaifa_List1Phase::MeterID); - meterType = hanReader.getString( (int)Kaifa_List1Phase::MeterType); - activeImportPower = hanReader.getInt( (int)Kaifa_List1Phase::ActiveImportPower); - reactiveImportPower = hanReader.getInt( (int)Kaifa_List1Phase::ReactiveImportPower); - activeExportPower = hanReader.getInt( (int)Kaifa_List1Phase::ActiveExportPower); - reactiveExportPower = hanReader.getInt( (int)Kaifa_List1Phase::ReactiveExportPower); - l1current = ((double) hanReader.getInt((int)Kaifa_List1Phase::CurrentL1)) / 1000; - l1voltage = ((double) hanReader.getInt((int)Kaifa_List1Phase::VoltageL1)) / 10; + listId = hanReader.getString( (int)Kaifa_List1Phase::ListVersionIdentifier); + meterId = hanReader.getString( (int)Kaifa_List1Phase::MeterID); + meterType = hanReader.getString( (int)Kaifa_List1Phase::MeterType); + activeImportPower = hanReader.getUint( (int)Kaifa_List1Phase::ActiveImportPower); + reactiveImportPower = hanReader.getUint( (int)Kaifa_List1Phase::ReactiveImportPower); + activeExportPower = hanReader.getUint( (int)Kaifa_List1Phase::ActiveExportPower); + reactiveExportPower = hanReader.getUint( (int)Kaifa_List1Phase::ReactiveExportPower); + l1current = ((double) hanReader.getInt( (int)Kaifa_List1Phase::CurrentL1)) / 1000; + l1voltage = ((double) hanReader.getInt( (int)Kaifa_List1Phase::VoltageL1)) / 10; break; } } @@ -107,23 +107,23 @@ void AmsData::extractFromAidon(HanReader& hanReader, int listSize) { } if(listSize == (int)Aidon::List1) { - activeImportPower = hanReader.getInt((int)Aidon_List1::ActiveImportPower); + activeImportPower = hanReader.getUint((int)Aidon_List1::ActiveImportPower); } else { switch(listSize) { case (int)Aidon::List3PhaseLong: meterTimestamp = hanReader.getTime( (int)Aidon_List3Phase::Timestamp); - activeImportCounter = ((double) hanReader.getInt( (int)Aidon_List3Phase::CumulativeActiveImportEnergy)) / 100; - activeExportCounter = ((double) hanReader.getInt( (int)Aidon_List3Phase::CumulativeActiveExportEnergy)) / 100; - reactiveImportCounter = ((double) hanReader.getInt( (int)Aidon_List3Phase::CumulativeReactiveImportEnergy)) / 100; - reactiveExportCounter = ((double) hanReader.getInt( (int)Aidon_List3Phase::CumulativeReactiveExportEnergy)) / 100; + activeImportCounter = ((double) hanReader.getUint( (int)Aidon_List3Phase::CumulativeActiveImportEnergy)) / 100; + activeExportCounter = ((double) hanReader.getUint( (int)Aidon_List3Phase::CumulativeActiveExportEnergy)) / 100; + reactiveImportCounter = ((double) hanReader.getUint( (int)Aidon_List3Phase::CumulativeReactiveImportEnergy)) / 100; + reactiveExportCounter = ((double) hanReader.getUint( (int)Aidon_List3Phase::CumulativeReactiveExportEnergy)) / 100; case (int)Aidon::List3PhaseShort: listId = hanReader.getString( (int)Aidon_List3Phase::ListVersionIdentifier); meterId = hanReader.getString( (int)Aidon_List3Phase::MeterID); meterType = hanReader.getString( (int)Aidon_List3Phase::MeterType); - activeImportPower = hanReader.getInt( (int)Aidon_List3Phase::ActiveImportPower); - reactiveImportPower = hanReader.getInt( (int)Aidon_List3Phase::ReactiveImportPower); - activeExportPower = hanReader.getInt( (int)Aidon_List3Phase::ActiveExportPower); - reactiveExportPower = hanReader.getInt( (int)Aidon_List3Phase::ReactiveExportPower); + activeImportPower = hanReader.getUint( (int)Aidon_List3Phase::ActiveImportPower); + reactiveImportPower = hanReader.getUint( (int)Aidon_List3Phase::ReactiveImportPower); + activeExportPower = hanReader.getUint( (int)Aidon_List3Phase::ActiveExportPower); + reactiveExportPower = hanReader.getUint( (int)Aidon_List3Phase::ReactiveExportPower); l1current = ((double) hanReader.getInt( (int)Aidon_List3Phase::CurrentL1)) / 10; l2current = ((double) hanReader.getInt( (int)Aidon_List3Phase::CurrentL2)) / 10; l3current = ((double) hanReader.getInt( (int)Aidon_List3Phase::CurrentL3)) / 10; @@ -133,35 +133,35 @@ void AmsData::extractFromAidon(HanReader& hanReader, int listSize) { break; case (int)Aidon::List1PhaseLong: meterTimestamp = hanReader.getTime( (int)Aidon_List1Phase::Timestamp); - activeImportCounter = ((double) hanReader.getInt( (int)Aidon_List1Phase::CumulativeActiveImportEnergy)) / 100; - activeExportCounter = ((double) hanReader.getInt( (int)Aidon_List1Phase::CumulativeActiveExportEnergy)) / 100; - reactiveImportCounter = ((double) hanReader.getInt( (int)Aidon_List1Phase::CumulativeReactiveImportEnergy)) / 100; - reactiveExportCounter = ((double) hanReader.getInt( (int)Aidon_List1Phase::CumulativeReactiveExportEnergy)) / 100; + activeImportCounter = ((double) hanReader.getUint( (int)Aidon_List1Phase::CumulativeActiveImportEnergy)) / 100; + activeExportCounter = ((double) hanReader.getUint( (int)Aidon_List1Phase::CumulativeActiveExportEnergy)) / 100; + reactiveImportCounter = ((double) hanReader.getUint( (int)Aidon_List1Phase::CumulativeReactiveImportEnergy)) / 100; + reactiveExportCounter = ((double) hanReader.getUint( (int)Aidon_List1Phase::CumulativeReactiveExportEnergy)) / 100; case (int)Aidon::List1PhaseShort: listId = hanReader.getString( (int)Aidon_List1Phase::ListVersionIdentifier); meterId = hanReader.getString( (int)Aidon_List1Phase::MeterID); meterType = hanReader.getString( (int)Aidon_List1Phase::MeterType); - activeImportPower = hanReader.getInt( (int)Aidon_List1Phase::ActiveImportPower); - reactiveImportPower = hanReader.getInt( (int)Aidon_List1Phase::ReactiveImportPower); - activeExportPower = hanReader.getInt( (int)Aidon_List1Phase::ActiveExportPower); - reactiveExportPower = hanReader.getInt( (int)Aidon_List1Phase::ReactiveExportPower); + activeImportPower = hanReader.getUint( (int)Aidon_List1Phase::ActiveImportPower); + reactiveImportPower = hanReader.getUint( (int)Aidon_List1Phase::ReactiveImportPower); + activeExportPower = hanReader.getUint( (int)Aidon_List1Phase::ActiveExportPower); + reactiveExportPower = hanReader.getUint( (int)Aidon_List1Phase::ReactiveExportPower); l1current = ((double) hanReader.getInt( (int)Aidon_List1Phase::CurrentL1)) / 10; l1voltage = ((double) hanReader.getInt( (int)Aidon_List1Phase::VoltageL1)) / 10; break; case (int)Aidon::List3PhaseITLong: meterTimestamp = hanReader.getTime( (int)Aidon_List3PhaseIT::Timestamp); - activeImportCounter = ((double) hanReader.getInt( (int)Aidon_List3PhaseIT::CumulativeActiveImportEnergy)) / 100; - activeExportCounter = ((double) hanReader.getInt( (int)Aidon_List3PhaseIT::CumulativeActiveExportEnergy)) / 100; - reactiveImportCounter = ((double) hanReader.getInt( (int)Aidon_List3PhaseIT::CumulativeReactiveImportEnergy)) / 100; - reactiveExportCounter = ((double) hanReader.getInt( (int)Aidon_List3PhaseIT::CumulativeReactiveExportEnergy)) / 100; + activeImportCounter = ((double) hanReader.getUint( (int)Aidon_List3PhaseIT::CumulativeActiveImportEnergy)) / 100; + activeExportCounter = ((double) hanReader.getUint( (int)Aidon_List3PhaseIT::CumulativeActiveExportEnergy)) / 100; + reactiveImportCounter = ((double) hanReader.getUint( (int)Aidon_List3PhaseIT::CumulativeReactiveImportEnergy)) / 100; + reactiveExportCounter = ((double) hanReader.getUint( (int)Aidon_List3PhaseIT::CumulativeReactiveExportEnergy)) / 100; case (int)Aidon::List3PhaseITShort: listId = hanReader.getString( (int)Aidon_List3PhaseIT::ListVersionIdentifier); meterId = hanReader.getString( (int)Aidon_List3PhaseIT::MeterID); meterType = hanReader.getString( (int)Aidon_List3PhaseIT::MeterType); - activeImportPower = hanReader.getInt( (int)Aidon_List3PhaseIT::ActiveImportPower); - reactiveImportPower = hanReader.getInt( (int)Aidon_List3PhaseIT::ReactiveImportPower); - activeExportPower = hanReader.getInt( (int)Aidon_List3PhaseIT::ActiveExportPower); - reactiveExportPower = hanReader.getInt( (int)Aidon_List3PhaseIT::ReactiveExportPower); + activeImportPower = hanReader.getUint( (int)Aidon_List3PhaseIT::ActiveImportPower); + reactiveImportPower = hanReader.getUint( (int)Aidon_List3PhaseIT::ReactiveImportPower); + activeExportPower = hanReader.getUint( (int)Aidon_List3PhaseIT::ActiveExportPower); + reactiveExportPower = hanReader.getUint( (int)Aidon_List3PhaseIT::ReactiveExportPower); l1current = ((double) hanReader.getInt( (int)Aidon_List3PhaseIT::CurrentL1)) / 10; l2current = 0; l3current = ((double) hanReader.getInt( (int)Aidon_List3PhaseIT::CurrentL3)) / 10; diff --git a/src/AmsToMqttBridge.ino b/src/AmsToMqttBridge.ino index b43cc7e2..aee17ecc 100644 --- a/src/AmsToMqttBridge.ino +++ b/src/AmsToMqttBridge.ino @@ -89,7 +89,7 @@ void setup() { #if SELF_POWERED if (vcc > 2.5 && vcc < 3.25) { // Only sleep if voltage is realistic and too low if(Debug.isActive(RemoteDebug::INFO)) { - debugI("Votltage is too low, sleeping"); + debugI("Voltage is too low, sleeping"); Serial.flush(); } ESP.deepSleep(10000000); //Deep sleep to allow output cap to charge up From cc72d0e0b3adabeeffc3cdcb746eb555400af036 Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Sat, 18 Apr 2020 19:18:39 +0200 Subject: [PATCH 2/2] Uncommited changes --- lib/HanReader/src/HanReader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/HanReader/src/HanReader.cpp b/lib/HanReader/src/HanReader.cpp index 78c5aca4..acec9893 100644 --- a/lib/HanReader/src/HanReader.cpp +++ b/lib/HanReader/src/HanReader.cpp @@ -203,7 +203,7 @@ int HanReader::getInt(int dataPosition, byte *buffer, int start, int length) { return getUint8(dataPosition, buffer, start, length); case 0x0F: return getInt8(dataPosition, buffer, start, length); - case 0x12: + case 0x12: return getUint16(dataPosition, buffer, start, length); case 0x10: return getInt16(dataPosition, buffer, start, length);