Added another proprietary L&G

This commit is contained in:
Gunnar Skjold
2023-03-30 08:59:56 +02:00
parent 51f761d25e
commit 0d923e30d6
6 changed files with 132 additions and 2 deletions

View File

@@ -70,6 +70,7 @@ ADC_MODE(ADC_VCC);
#include "IEC6205621.h"
#include "IEC6205675.h"
#include "LNG.h"
#include "LNG2.h"
#include "DataParsers.h"
#include "Timezones.h"
@@ -918,10 +919,22 @@ bool readHanPort() {
debugV("Using application data:");
if(Debug.isActive(RemoteDebug::VERBOSE)) debugPrint((byte*) payload, 0, ctx.length);
// Rudimentary detector for L&G proprietary format
// Rudimentary detector for L&G proprietary format, this is terrible code... Fix later
if(payload[0] == CosemTypeStructure && payload[2] == CosemTypeArray && payload[1] == payload[3]) {
debugV("LNG");
data = LNG(payload, meterState.getMeterType(), &meterConfig, ctx, &Debug);
} else if(payload[0] == CosemTypeStructure &&
payload[2] == CosemTypeLongUnsigned &&
payload[5] == CosemTypeLongUnsigned &&
payload[8] == CosemTypeLongUnsigned &&
payload[11] == CosemTypeLongUnsigned &&
payload[14] == CosemTypeLongUnsigned &&
payload[17] == CosemTypeLongUnsigned
) {
debugV("LNG2");
data = LNG2(payload, meterState.getMeterType(), &meterConfig, ctx, &Debug);
} else {
debugV("DLMS");
// TODO: Split IEC6205675 into DataParserKaifa and DataParserObis. This way we can add other means of parsing, for those other proprietary formats
data = IEC6205675(payload, meterState.getMeterType(), &meterConfig, ctx);
}

43
src/LNG2.cpp Normal file
View File

@@ -0,0 +1,43 @@
#include "LNG2.h"
LNG2::LNG2(const char* payload, uint8_t useMeterType, MeterConfig* meterConfig, DataParserContext &ctx, RemoteDebug* debugger) {
CosemBasic* h = (CosemBasic*) payload;
if(h->length == 0x0e) {
Lng2Data_3p* d = (Lng2Data_3p*) payload;
this->l1voltage = ntohs(d->u1.data);
this->l2voltage = ntohs(d->u2.data);
this->l3voltage = ntohs(d->u3.data);
this->l1current = ntohs(d->i1.data) / 100.0;
this->l2current = ntohs(d->i2.data) / 100.0;
this->l3current = ntohs(d->i3.data) / 100.0;
this->activeImportPower = ntohl(d->activeImport.data);
this->activeExportPower = ntohl(d->activeExport.data);
this->activeImportCounter = ntohl(d->acumulatedImport.data) / 1000.0;
this->activeExportCounter = ntohl(d->accumulatedExport.data) / 1000.0;
char str[64];
uint8_t str_len = getString((CosemData*) &d->meterId, str);
if(str_len > 0) {
this->meterId = String(str);
}
listType = 3;
lastUpdateMillis = millis();
}
}
uint8_t LNG2::getString(CosemData* item, char* target) {
switch(item->base.type) {
case CosemTypeString:
memcpy(target, item->str.data, item->str.length);
target[item->str.length] = 0;
return item->str.length;
case CosemTypeOctetString:
memcpy(target, item->oct.data, item->oct.length);
target[item->oct.length] = 0;
return item->oct.length;
}
return 0;
}

37
src/LNG2.h Normal file
View File

@@ -0,0 +1,37 @@
#ifndef _LNG2_H
#define _LNG2_H
#include "AmsData.h"
#include "AmsConfiguration.h"
#include "DataParser.h"
#include "Cosem.h"
#include "RemoteDebug.h"
struct Lng2Data_3p {
CosemBasic header;
CosemLongUnsigned u1;
CosemLongUnsigned u2;
CosemLongUnsigned u3;
CosemLongUnsigned i1;
CosemLongUnsigned i2;
CosemLongUnsigned i3;
CosemDLongUnsigned activeImport;
CosemDLongUnsigned activeExport;
CosemDLongUnsigned acumulatedImport;
CosemDLongUnsigned accumulatedExport;
CosemLongUnsigned x;
CosemLongUnsigned y;
CosemLongUnsigned z;
CosemString meterId;
} __attribute__((packed));
class LNG2 : public AmsData {
public:
LNG2(const char* payload, uint8_t useMeterType, MeterConfig* meterConfig, DataParserContext &ctx, RemoteDebug* debugger);
private:
uint8_t getString(CosemData* item, char* target);
};
#endif