From 5beb13894c9a01100a3a4ed9d3c19ccd3a2dc6ee Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Sat, 9 Jan 2021 11:11:49 +0100 Subject: [PATCH] Initial implementation of supporting timezone in timestamp --- lib/HanReader/src/HanReader.cpp | 21 ++++++++++++++------- lib/HanReader/src/HanReader.h | 8 ++++---- src/AmsData.cpp | 20 ++++++++++---------- 3 files changed, 28 insertions(+), 21 deletions(-) diff --git a/lib/HanReader/src/HanReader.cpp b/lib/HanReader/src/HanReader.cpp index 4d18d501..170f16e4 100644 --- a/lib/HanReader/src/HanReader.cpp +++ b/lib/HanReader/src/HanReader.cpp @@ -169,15 +169,15 @@ int HanReader::getListSize() { return listSize; } -time_t HanReader::getPackageTime() { +time_t HanReader::getPackageTime(bool respectTimezone, bool respectDsc) { int packageTimePosition = dataHeader + (compensateFor09HeaderBug ? 1 : 0); - return getTime(buffer, packageTimePosition, bytesRead); + return getTime(buffer, packageTimePosition, bytesRead, respectTimezone, respectDsc); } -time_t HanReader::getTime(int objectId) { - return getTime(objectId, buffer, 0, bytesRead); +time_t HanReader::getTime(int objectId, bool respectTimezone, bool respectDsc) { + return getTime(objectId, respectTimezone, respectDsc, buffer, 0, bytesRead); } int32_t HanReader::getInt(int objectId) { @@ -240,14 +240,14 @@ int HanReader::findValuePosition(int dataPosition, byte *buffer, int start, int } -time_t HanReader::getTime(int dataPosition, byte *buffer, int start, int length) { +time_t HanReader::getTime(int dataPosition, bool respectTimezone, bool respectDsc, 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 += 1; - return getTime(buffer, start + timeStart, length - timeStart); + return getTime(buffer, start + timeStart, length - timeStart, respectTimezone, respectDsc); } -time_t HanReader::getTime(byte *buffer, int start, int length) { +time_t HanReader::getTime(byte *buffer, int start, int length, bool respectTimezone, bool respectDsc) { int pos = start; int dataLength = buffer[pos++]; @@ -257,9 +257,16 @@ time_t HanReader::getTime(byte *buffer, int start, int length) { int month = buffer[pos + 2]; int day = buffer[pos + 3]; + // 4: Day of week int hour = buffer[pos + 5]; int minute = buffer[pos + 6]; int second = buffer[pos + 7]; + // 8: Hundredths + int tzMinutes = buffer[pos + 9] << 8 | buffer[pos + 10]; + bool dsc = (buffer[pos + 11] & 0x01) == 0x01; + + printD("Time offset: %d", tzMinutes); + printD(dsc ? "DSC" : "not DSC"); tmElements_t tm; tm.Year = year - 1970; diff --git a/lib/HanReader/src/HanReader.h b/lib/HanReader/src/HanReader.h index 980a2d54..f4a4906d 100644 --- a/lib/HanReader/src/HanReader.h +++ b/lib/HanReader/src/HanReader.h @@ -24,11 +24,11 @@ public: bool read(); bool read(byte data); int getListSize(); - time_t getPackageTime(); + time_t getPackageTime(bool respectTimezone, bool respectDsc); 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); + time_t getTime(int objectId, bool respectTimezone, bool respectDsc); int getBuffer(byte* buf); void setEncryptionKey(uint8_t* encryption_key); @@ -47,8 +47,8 @@ private: int findValuePosition(int dataPosition, byte *buffer, int start, int length); - time_t getTime(int dataPosition, byte *buffer, int start, int length); - time_t getTime(byte *buffer, int start, int length); + time_t getTime(int dataPosition, bool respectTimezone, bool respectDsc, byte *buffer, int start, int length); + time_t getTime(byte *buffer, int start, int length, bool respectTimezone, bool respectDsc); 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); diff --git a/src/AmsData.cpp b/src/AmsData.cpp index 267c3a76..9295af95 100644 --- a/src/AmsData.cpp +++ b/src/AmsData.cpp @@ -8,7 +8,7 @@ AmsData::AmsData() {} AmsData::AmsData(int meterType, bool substituteMissing, HanReader& hanReader) { lastUpdateMillis = millis(); - packageTimestamp = hanReader.getPackageTime(); + packageTimestamp = hanReader.getPackageTime(true, true); int listSize = hanReader.getListSize(); switch(meterType) { @@ -49,7 +49,7 @@ void AmsData::extractFromKaifa(HanReader& hanReader, int listSize) { } else { switch(listSize) { case (int)Kaifa::List3PhaseLong: - meterTimestamp = hanReader.getTime( (int)Kaifa_List3Phase::MeterClock); + meterTimestamp = hanReader.getTime( (int)Kaifa_List3Phase::MeterClock, false, false); 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; @@ -70,7 +70,7 @@ void AmsData::extractFromKaifa(HanReader& hanReader, int listSize) { l3voltage = ((double) hanReader.getInt( (int)Kaifa_List3Phase::VoltageL3)) / 10; break; case (int)Kaifa::List1PhaseLong: - meterTimestamp = hanReader.getTime( (int)Kaifa_List1Phase::MeterClock); + meterTimestamp = hanReader.getTime( (int)Kaifa_List1Phase::MeterClock, false, false); activeImportCounter = ((double) hanReader.getUint((int)Kaifa_List1Phase::CumulativeActiveImportEnergy)); activeExportCounter = ((double) hanReader.getUint((int)Kaifa_List1Phase::CumulativeActiveExportEnergy)); reactiveImportCounter = ((double) hanReader.getUint((int)Kaifa_List1Phase::CumulativeReactiveImportEnergy)); @@ -114,7 +114,7 @@ void AmsData::extractFromAidon(HanReader& hanReader, int listSize, bool substitu } else { switch(listSize) { case (int)Aidon::List3PhaseLong: - meterTimestamp = hanReader.getTime( (int)Aidon_List3Phase::Timestamp); + meterTimestamp = hanReader.getTime( (int)Aidon_List3Phase::Timestamp, false, false); 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; @@ -135,7 +135,7 @@ void AmsData::extractFromAidon(HanReader& hanReader, int listSize, bool substitu l3voltage = ((double) hanReader.getInt( (int)Aidon_List3Phase::VoltageL3)) / 10; break; case (int)Aidon::List1PhaseLong: - meterTimestamp = hanReader.getTime( (int)Aidon_List1Phase::Timestamp); + meterTimestamp = hanReader.getTime( (int)Aidon_List1Phase::Timestamp, false, false); 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; @@ -152,7 +152,7 @@ void AmsData::extractFromAidon(HanReader& hanReader, int listSize, bool substitu l1voltage = ((double) hanReader.getInt( (int)Aidon_List1Phase::VoltageL1)) / 10; break; case (int)Aidon::List3PhaseITLong: - meterTimestamp = hanReader.getTime( (int)Aidon_List3PhaseIT::Timestamp); + meterTimestamp = hanReader.getTime( (int)Aidon_List3PhaseIT::Timestamp, false, false); 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; @@ -197,7 +197,7 @@ void AmsData::extractFromKamstrup(HanReader& hanReader, int listSize, bool subst switch(listSize) { case (int)Kamstrup::List1PhaseLong: - meterTimestamp = hanReader.getTime( (int)Kamstrup_List1Phase::MeterClock); + meterTimestamp = hanReader.getTime( (int)Kamstrup_List1Phase::MeterClock, true, true); activeImportCounter = ((double) hanReader.getInt((int)Kamstrup_List1Phase::CumulativeActiveImportEnergy)) / 100; activeExportCounter = ((double) hanReader.getInt((int)Kamstrup_List1Phase::CumulativeActiveExportEnergy)) / 100; reactiveImportCounter = ((double) hanReader.getInt((int)Kamstrup_List1Phase::CumulativeReactiveImportEnergy)) / 100; @@ -214,7 +214,7 @@ void AmsData::extractFromKamstrup(HanReader& hanReader, int listSize, bool subst l1voltage = hanReader.getInt( (int)Kamstrup_List1Phase::VoltageL1); break; case (int)Kamstrup::List3PhaseLong: - meterTimestamp = hanReader.getTime( (int)Kamstrup_List3Phase::MeterClock); + meterTimestamp = hanReader.getTime( (int)Kamstrup_List3Phase::MeterClock, true, true); activeImportCounter = ((double) hanReader.getInt((int)Kamstrup_List3Phase::CumulativeActiveImportEnergy)) / 100; activeExportCounter = ((double) hanReader.getInt((int)Kamstrup_List3Phase::CumulativeActiveExportEnergy)) / 100; reactiveImportCounter = ((double) hanReader.getInt((int)Kamstrup_List3Phase::CumulativeReactiveImportEnergy)) / 100; @@ -235,7 +235,7 @@ void AmsData::extractFromKamstrup(HanReader& hanReader, int listSize, bool subst l3voltage = hanReader.getInt( (int)Kamstrup_List3Phase::VoltageL3); break; case (int)Kamstrup::List3PhaseITLong: - meterTimestamp = hanReader.getTime( (int)Kamstrup_List3Phase::MeterClock); + meterTimestamp = hanReader.getTime( (int)Kamstrup_List3Phase::MeterClock, true, true); activeImportCounter = ((double) hanReader.getInt((int)Kamstrup_List3Phase::CumulativeActiveImportEnergy)) / 100; activeExportCounter = ((double) hanReader.getInt((int)Kamstrup_List3Phase::CumulativeActiveExportEnergy)) / 100; reactiveImportCounter = ((double) hanReader.getInt((int)Kamstrup_List3Phase::CumulativeReactiveImportEnergy)) / 100; @@ -264,7 +264,7 @@ void AmsData::extractFromKamstrup(HanReader& hanReader, int listSize, bool subst void AmsData::extractFromOmnipower(HanReader& hanReader, int listSize) { switch(listSize) { case (int)Omnipower::DLMS: - meterTimestamp = hanReader.getTime( (int)Omnipower_DLMS::MeterClock); + meterTimestamp = hanReader.getTime( (int)Omnipower_DLMS::MeterClock, true, true); activeImportCounter = ((double) hanReader.getInt((int)Omnipower_DLMS::CumulativeActiveImportEnergy)) / 100; activeExportCounter = ((double) hanReader.getInt((int)Omnipower_DLMS::CumulativeActiveExportEnergy)) / 100; reactiveImportCounter = ((double) hanReader.getInt((int)Omnipower_DLMS::CumulativeReactiveImportEnergy)) / 100;