From 633671851e8cde9df144ea8bf635a582d5c3237e Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Thu, 25 Sep 2025 10:47:47 +0200 Subject: [PATCH] Fixed Kamstrup timestamp parsing (#1011) * Fixed kamstrup timestamp deviation * Fixed check for time zone --- lib/AmsDecoder/src/Cosem.cpp | 2 -- lib/MeterCommunicators/include/IEC6205675.h | 9 ++++++++- lib/MeterCommunicators/src/IEC6205675.cpp | 18 ++++++++++-------- .../src/PassiveMeterCommunicator.cpp | 2 +- 4 files changed, 19 insertions(+), 12 deletions(-) diff --git a/lib/AmsDecoder/src/Cosem.cpp b/lib/AmsDecoder/src/Cosem.cpp index 4cf3075a..cbf0c78f 100644 --- a/lib/AmsDecoder/src/Cosem.cpp +++ b/lib/AmsDecoder/src/Cosem.cpp @@ -19,8 +19,6 @@ time_t decodeCosemDateTime(CosemDateTime timestamp) { tm.Minute = timestamp.minute; tm.Second = timestamp.second; - //Serial.printf("\nY: %d, M: %d, D: %d, h: %d, m: %d, s: %d, deviation: 0x%2X, status: 0x%1X\n", tm.Year, tm.Month, tm.Day, tm.Hour, tm.Minute, tm.Second, timestamp.deviation, timestamp.status); - time_t time = makeTime(tm); int16_t deviation = ntohs(timestamp.deviation); if(deviation >= -720 && deviation <= 720) { diff --git a/lib/MeterCommunicators/include/IEC6205675.h b/lib/MeterCommunicators/include/IEC6205675.h index f4aaa9bb..3cd82b22 100644 --- a/lib/MeterCommunicators/include/IEC6205675.h +++ b/lib/MeterCommunicators/include/IEC6205675.h @@ -11,6 +11,9 @@ #include "AmsConfiguration.h" #include "DataParser.h" #include "Cosem.h" +#if defined(AMS_REMOTE_DEBUG) +#include "RemoteDebug.h" +#endif #define NOVALUE 0xFFFFFFFF @@ -21,7 +24,11 @@ struct AmsOctetTimestamp { class IEC6205675 : public AmsData { public: - IEC6205675(const char* payload, uint8_t useMeterType, MeterConfig* meterConfig, DataParserContext &ctx, AmsData &state); + #if defined(AMS_REMOTE_DEBUG) + IEC6205675(const char* payload, uint8_t useMeterType, MeterConfig* meterConfig, DataParserContext &ctx, AmsData &state, RemoteDebug* debugger); + #else + IEC6205675(const char* payload, uint8_t useMeterType, MeterConfig* meterConfig, DataParserContext &ctx, AmsData &state, Stream* debugger); + #endif private: CosemData* getCosemDataAt(uint8_t index, const char* ptr); diff --git a/lib/MeterCommunicators/src/IEC6205675.cpp b/lib/MeterCommunicators/src/IEC6205675.cpp index b02e7a35..17ccebed 100644 --- a/lib/MeterCommunicators/src/IEC6205675.cpp +++ b/lib/MeterCommunicators/src/IEC6205675.cpp @@ -11,7 +11,11 @@ #include "Uptime.h" #include "hexutils.h" -IEC6205675::IEC6205675(const char* d, uint8_t useMeterType, MeterConfig* meterConfig, DataParserContext &ctx, AmsData &state) { +#if defined(AMS_REMOTE_DEBUG) +IEC6205675::IEC6205675(const char* d, uint8_t useMeterType, MeterConfig* meterConfig, DataParserContext &ctx, AmsData &state, RemoteDebug* debugger) { +#else +IEC6205675::IEC6205675(const char* payload, uint8_t useMeterType, MeterConfig* meterConfig, DataParserContext &ctx, AmsData &state, Stream* debugger) { +#endif float val; char str[64]; @@ -635,12 +639,6 @@ IEC6205675::IEC6205675(const char* d, uint8_t useMeterType, MeterConfig* meterCo } } - if(this->packageTimestamp > 0) { - if(meterType == AmsTypeKamstrup) { - this->packageTimestamp = this->packageTimestamp - 3600; - } - } - uint8_t str_len = 0; str_len = getString(AMS_OBIS_VERSION, sizeof(AMS_OBIS_VERSION), ((char *) (d)), str); if(str_len > 0) { @@ -741,8 +739,12 @@ IEC6205675::IEC6205675(const char* d, uint8_t useMeterType, MeterConfig* meterCo if(meterTs != NULL) { AmsOctetTimestamp* amst = (AmsOctetTimestamp*) meterTs; time_t ts = decodeCosemDateTime(amst->dt); - if(amst->dt.deviation == 0x8000) { // Deviation not specified, adjust from localtime to UTC + int16_t deviation = ntohs(amst->dt.deviation); + if(deviation < -720 || deviation > 720) { // Deviation not specified, adjust from localtime to UTC meterTimestamp = tz.toUTC(ts); + if(ctx.timestamp > 0) { + this->packageTimestamp = tz.toUTC(ctx.timestamp); + } } else if(meterType == AmsTypeAidon) { meterTimestamp = ts - 3600; // 21.09.24, the clock is now correct } else { diff --git a/lib/MeterCommunicators/src/PassiveMeterCommunicator.cpp b/lib/MeterCommunicators/src/PassiveMeterCommunicator.cpp index ce51e106..60b499c8 100644 --- a/lib/MeterCommunicators/src/PassiveMeterCommunicator.cpp +++ b/lib/MeterCommunicators/src/PassiveMeterCommunicator.cpp @@ -278,7 +278,7 @@ AmsData* PassiveMeterCommunicator::getData(AmsData& meterState) { #endif debugger->printf_P(PSTR("DLMS\n")); // TODO: Split IEC6205675 into DataParserKaifa and DataParserObis. This way we can add other means of parsing, for those other proprietary formats - data = new IEC6205675(payload, meterState.getMeterType(), &meterConfig, ctx, meterState); + data = new IEC6205675(payload, meterState.getMeterType(), &meterConfig, ctx, meterState, debugger); } } else if(ctx.type == DATA_TAG_DSMR) { data = new IEC6205621(payload, tz, &meterConfig);