Support different size numbers in L&G payload

This commit is contained in:
Gunnar Skjold
2022-11-01 18:41:43 +01:00
parent 6c0d5fcc09
commit 775e5a0881
3 changed files with 68 additions and 24 deletions

View File

@@ -810,7 +810,7 @@ bool readHanPort() {
hanBuffer[len++] = hanSerial->read();
ctx.length = len;
pos = unwrapData((uint8_t *) hanBuffer, ctx);
if(pos >= 0) {
if(ctx.type > 0 && pos >= 0) {
if(ctx.type == DATA_TAG_DLMS) {
debugV("Received valid DLMS at %d", pos);
} else if(ctx.type == DATA_TAG_DSMR) {
@@ -826,6 +826,7 @@ bool readHanPort() {
if(pos == DATA_PARSE_INCOMPLETE) {
return false;
} else if(pos == DATA_PARSE_UNKNOWN_DATA) {
debugV("Unknown data payload:");
len = len + hanSerial->readBytes(hanBuffer+len, BUF_SIZE_HAN-len);
debugPrint(hanBuffer, 0, len);
len = 0;
@@ -1175,7 +1176,7 @@ int16_t unwrapData(uint8_t *buf, DataParserContext &context) {
if(res >= 0) doRet = true;
break;
default:
debugE("Ended up in default case while unwrapping...");
debugE("Ended up in default case while unwrapping...(tag %02X)", tag);
return DATA_PARSE_UNKNOWN_DATA;
}
lastTag = tag;

View File

@@ -1,6 +1,6 @@
#include "LNG.h"
#include "lwip/def.h"
#include "ams/Cosem.h"
#include "ams/ntohll.h"
LNG::LNG(const char* payload, uint8_t useMeterType, MeterConfig* meterConfig, DataParserContext &ctx, RemoteDebug* debugger) {
LngHeader* h = (LngHeader*) payload;
@@ -11,9 +11,10 @@ LNG::LNG(const char* payload, uint8_t useMeterType, MeterConfig* meterConfig, Da
uint8_t* ptr = (uint8_t*) &h[1];
uint8_t* data = ptr + (18*h->arrayLength); // Skip descriptors
uint16_t o170 = 0, o270 = 0;
uint16_t o181 = 0, o182 = 0;
uint16_t o281 = 0, o282 = 0;
uint64_t o170 = 0, o270 = 0;
uint64_t o180 = 0, o280 = 0;
uint64_t o181 = 0, o182 = 0;
uint64_t o281 = 0, o282 = 0;
LngObisDescriptor* descriptor = (LngObisDescriptor*) ptr;
for(uint8_t x = 0; x < h->arrayLength-1; x++) {
ptr = (uint8_t*) &descriptor[1];
@@ -24,39 +25,41 @@ LNG::LNG(const char* payload, uint8_t useMeterType, MeterConfig* meterConfig, Da
if(descriptor->obis[2] == 1) {
if(descriptor->obis[3] == 7) {
if(descriptor->obis[4] == 0) {
o170 = ntohl(item->dlu.data);
if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %lu (dlu)", ntohl(item->dlu.data));
o170 = getNumber(item);
if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %lu", o170);
}
} else if(descriptor->obis[3] == 8) {
if(descriptor->obis[4] == 0) {
activeImportCounter = ntohl(item->dlu.data) / 1000.0;
o180 = getNumber(item);
listType = listType >= 3 ? listType : 3;
if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %lu (dlu)", ntohl(item->dlu.data));
if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %lu", o180);
activeImportCounter = o180 / 1000.0;
} else if(descriptor->obis[4] == 1) {
o181 = ntohl(item->dlu.data);
if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %lu (dlu)", ntohl(item->dlu.data));
o181 = getNumber(item);
if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %lu", o181);
} else if(descriptor->obis[4] == 2) {
o182 = ntohl(item->dlu.data);
if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %lu (dlu)", ntohl(item->dlu.data));
o182 = getNumber(item);
if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %lu", o182);
}
}
} else if(descriptor->obis[2] == 2) {
if(descriptor->obis[3] == 7) {
if(descriptor->obis[4] == 0) {
o270 = ntohl(item->dlu.data);
if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %lu (dlu)", ntohl(item->dlu.data));
o270 = getNumber(item);
if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %lu", o270);
}
} else if(descriptor->obis[3] == 8) {
if(descriptor->obis[4] == 0) {
activeExportCounter = ntohl(item->dlu.data) / 1000.0;
o280 = getNumber(item);
listType = listType >= 3 ? listType : 3;
if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %lu (dlu)", ntohl(item->dlu.data));
if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %lu", o280);
activeExportCounter = o280 / 1000.0;
} else if(descriptor->obis[4] == 1) {
o281 = ntohl(item->dlu.data);
if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %lu (dlu)", ntohl(item->dlu.data));
o281 = getNumber(item);
if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %lu", o281);
} else if(descriptor->obis[4] == 2) {
o282 = ntohl(item->dlu.data);
if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %lu (dlu)", ntohl(item->dlu.data));
o282 = getNumber(item);
if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %lu", o282);
}
}
} else if(descriptor->obis[2] == 96) {
@@ -101,11 +104,49 @@ LNG::LNG(const char* payload, uint8_t useMeterType, MeterConfig* meterConfig, Da
if((*data) == 0x09) {
data += (*(data+1))+2;
} else {
} else if((*data) == 0x15) {
data += 9;
} else if((*data) == 0x06) {
data += 5;
} else if((*data) == 0x12) {
data += 3;
}
lastUpdateMillis = millis();
}
}
}
}
uint64_t LNG::getNumber(CosemData* item) {
if(item != NULL) {
uint64_t ret = 0.0;
switch(item->base.type) {
case CosemTypeLongSigned: {
int16_t i16 = ntohs(item->ls.data);
return i16;
}
case CosemTypeLongUnsigned: {
uint16_t u16 = ntohs(item->lu.data);
return u16;
}
case CosemTypeDLongSigned: {
int32_t i32 = ntohl(item->dlu.data);
return i32;
}
case CosemTypeDLongUnsigned: {
uint32_t u32 = ntohl(item->dlu.data);
return u32;
}
case CosemTypeLong64Signed: {
int64_t i64 = ntohll(item->l64s.data);
return i64;
}
case CosemTypeLong64Unsigned: {
uint64_t u64 = ntohll(item->l64u.data);
return u64;
}
}
return ret;
}
return 0.0;
}

View File

@@ -4,6 +4,7 @@
#include "AmsData.h"
#include "AmsConfiguration.h"
#include "ams/DataParser.h"
#include "ams/Cosem.h"
#include "RemoteDebug.h"
struct LngHeader {
@@ -25,6 +26,7 @@ struct LngObisDescriptor {
class LNG : public AmsData {
public:
LNG(const char* payload, uint8_t useMeterType, MeterConfig* meterConfig, DataParserContext &ctx, RemoteDebug* debugger);
uint64_t getNumber(CosemData* item);
};
#endif