Untestet L&G data parser

This commit is contained in:
Gunnar Skjold 2022-08-16 08:22:43 +02:00
parent 998b986604
commit a055465ce0
6 changed files with 135 additions and 1 deletions

View File

@ -43,3 +43,37 @@ FF // Last byte of OBIS in previous block
0600000000 // Accumulated export
8BA4
7E
7E A1 23 CE FF 03 13 21 55 E6 E7 00
0F 00 00 08 E2
0C 07 E5 07 13 01 0C 1A 0A FF 80 00 00
02 0B // 11
01 0B // 11
02 04 12 00 28 09 06 00 08 19 09 00 FF 0F 02 12 00 00
02 04 12 00 28 09 06 00 08 19 09 00 FF 0F 01 12 00 00
02 04 12 00 01 09 06 00 00 60 01 00 FF 0F 02 12 00 00
02 04 12 00 03 09 06 01 00 01 07 00 FF 0F 02 12 00 00
02 04 12 00 03 09 06 01 00 02 07 00 FF 0F 02 12 00 00
02 04 12 00 03 09 06 01 01 01 08 00 FF 0F 02 12 00 00
02 04 12 00 03 09 06 01 01 02 08 00 FF 0F 02 12 00 00
02 04 12 00 03 09 06 01 01 05 08 00 FF 0F 02 12 00 00
02 04 12 00 03 09 06 01 01 06 08 00 FF 0F 02 12 00 00
02 04 12 00 03 09 06 01 01 07 08 00 FF 0F 02 12 00 00
02 04 12 00 03 09 06 01 01 08 08 00 FF 0F 02 12 00 00
09 06 00 08 19 09 00 FF
09 08 34 33 30 39 34 33 35 31
06 00 00 00 0B
06 00 00 00 00
06 00 00 00 10
06 00 00 00 04
06 00 00 00 00
06 00 00 00 08
06 00 00 00 00
06 00 00 00 01
7C 8B
7E

View File

@ -12,6 +12,7 @@ enum AmsType {
AmsTypeIskra = 0x08,
AmsTypeLandis = 0x09,
AmsTypeSagemcom = 0x0A,
AmsTypeLng = 0x0B,
AmsTypeCustom = 0x88,
AmsTypeUnknown = 0xFF
};

View File

@ -65,6 +65,7 @@ ADC_MODE(ADC_VCC);
#include "IEC6205621.h"
#include "IEC6205675.h"
#include "LNG.h"
#include "ams/DataParsers.h"
@ -851,7 +852,8 @@ bool readHanPort() {
if(Debug.isActive(RemoteDebug::VERBOSE)) debugPrint(hanBuffer+pos, 0, ctx.length);
// TODO: Split IEC6205675 into DataParserKaifa and DataParserObis. This way we can add other means of parsing, for those other proprietary formats
data = IEC6205675(((char *) (hanBuffer)) + pos, meterState.getMeterType(), &meterConfig, ctx);
//data = IEC6205675(((char *) (hanBuffer)) + pos, meterState.getMeterType(), &meterConfig, ctx);
data = LNG(((char *) (hanBuffer)) + pos, meterState.getMeterType(), &meterConfig, ctx);
} else if(ctx.type == DATA_TAG_DSMR) {
data = IEC6205621(((char *) (hanBuffer)) + pos);
}

65
src/LNG.cpp Normal file
View File

@ -0,0 +1,65 @@
#include "LNG.h"
#include "lwip/def.h"
#include "ams/Cosem.h"
LNG::LNG(const char* payload, uint8_t useMeterType, MeterConfig* meterConfig, DataParserContext &ctx) {
LngHeader* h = (LngHeader*) payload;
if(h->tag == CosemTypeStructure && h->arrayTag == CosemTypeArray) {
meterType = AmsTypeLng;
this->packageTimestamp = ctx.timestamp;
uint8_t* ptr = (uint8_t*) &h[1];
uint8_t* data = ptr + (18*h->arrayLength); // Skip descriptors
for(uint8_t i = 0; i < h->arrayLength; i++) {
LngObisDescriptor* descriptor = (LngObisDescriptor*) ptr;
if(descriptor->obis[2] == 1) {
if(descriptor->obis[3] == 7) {
if(descriptor->obis[4] == 0) {
CosemDLongUnsigned* item = (CosemDLongUnsigned*) data;
activeImportPower = ntohl(item->data);
listType = listType >= 1 ? listType : 1;
}
} else if(descriptor->obis[3] == 8) {
if(descriptor->obis[4] == 0) {
CosemDLongUnsigned* item = (CosemDLongUnsigned*) data;
activeImportCounter = ntohl(item->data);
listType = listType >= 3 ? listType : 3;
}
}
} else if(descriptor->obis[2] == 2) {
if(descriptor->obis[3] == 7) {
if(descriptor->obis[4] == 0) {
CosemDLongUnsigned* item = (CosemDLongUnsigned*) data;
activeExportPower = ntohl(item->data);
listType = listType >= 2 ? listType : 2;
}
} else if(descriptor->obis[3] == 8) {
if(descriptor->obis[4] == 0) {
CosemDLongUnsigned* item = (CosemDLongUnsigned*) data;
activeExportCounter = ntohl(item->data);
listType = listType >= 3 ? listType : 3;
}
}
} else if(descriptor->obis[2] == 96) {
if(descriptor->obis[3] == 1) {
if(descriptor->obis[4] == 0) {
CosemString* item = (CosemString*) data;
char str[item->length+1];
memcpy(str, item->data, item->length);
str[item->length] = '\0';
meterId = String(str);
}
}
}
ptr = (uint8_t*) &descriptor[1];
if((*data) == 0x09) {
data += (*data+1)+2;
} else {
data += 5;
}
}
}
}

29
src/LNG.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef _LNG_H
#define _LNG_H
#include "AmsData.h"
#include "AmsConfiguration.h"
#include "ams/DataParser.h"
struct LngHeader {
uint8_t tag;
uint8_t values;
uint8_t arrayTag;
uint8_t arrayLength;
} __attribute__((packed));
struct LngObisDescriptor {
uint8_t ignore1[5];
uint8_t octetTag;
uint8_t octetLength;
uint8_t obis[6];
uint8_t ignore2[5];
} __attribute__((packed));
class LNG : public AmsData {
public:
LNG(const char* payload, uint8_t useMeterType, MeterConfig* meterConfig, DataParserContext &ctx);
};
#endif

View File

@ -336,6 +336,9 @@ void AmsWebServer::configMeterHtml() {
case AmsTypeSagemcom:
manufacturer = "Sagemcom";
break;
case AmsTypeLng:
manufacturer = "L&G";
break;
default:
manufacturer = "Unknown";
break;