mirror of
https://github.com/UtilitechAS/amsreader-firmware.git
synced 2026-01-14 15:54:47 +00:00
153 lines
6.4 KiB
C++
153 lines
6.4 KiB
C++
#include "LNG.h"
|
|
#include "lwip/def.h"
|
|
#include "ams/ntohll.h"
|
|
|
|
LNG::LNG(const char* payload, uint8_t useMeterType, MeterConfig* meterConfig, DataParserContext &ctx, RemoteDebug* debugger) {
|
|
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
|
|
|
|
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];
|
|
descriptor = (LngObisDescriptor*) ptr;
|
|
if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf("(L&G) OBIS %d.%d.%d with type 0x%02X", descriptor->obis[2], descriptor->obis[3], descriptor->obis[4], *data);
|
|
|
|
CosemData* item = (CosemData*) data;
|
|
if(descriptor->obis[2] == 1) {
|
|
if(descriptor->obis[3] == 7) {
|
|
if(descriptor->obis[4] == 0) {
|
|
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) {
|
|
o180 = getNumber(item);
|
|
listType = listType >= 3 ? listType : 3;
|
|
if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %lu", o180);
|
|
activeImportCounter = o180 / 1000.0;
|
|
} else if(descriptor->obis[4] == 1) {
|
|
o181 = getNumber(item);
|
|
if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %lu", o181);
|
|
} else if(descriptor->obis[4] == 2) {
|
|
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 = getNumber(item);
|
|
if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %lu", o270);
|
|
}
|
|
} else if(descriptor->obis[3] == 8) {
|
|
if(descriptor->obis[4] == 0) {
|
|
o280 = getNumber(item);
|
|
listType = listType >= 3 ? listType : 3;
|
|
if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %lu", o280);
|
|
activeExportCounter = o280 / 1000.0;
|
|
} else if(descriptor->obis[4] == 1) {
|
|
o281 = getNumber(item);
|
|
if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %lu", o281);
|
|
} else if(descriptor->obis[4] == 2) {
|
|
o282 = getNumber(item);
|
|
if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %lu", o282);
|
|
}
|
|
}
|
|
} else if(descriptor->obis[2] == 96) {
|
|
if(descriptor->obis[3] == 1) {
|
|
if(descriptor->obis[4] == 0) {
|
|
char str[item->oct.length+1];
|
|
memcpy(str, item->oct.data, item->oct.length);
|
|
str[item->oct.length] = '\0';
|
|
meterId = String(str);
|
|
if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %s (oct)", str);
|
|
} else if(descriptor->obis[4] == 1) {
|
|
char str[item->oct.length+1];
|
|
memcpy(str, item->oct.data, item->oct.length);
|
|
str[item->oct.length] = '\0';
|
|
meterModel = String(str);
|
|
if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %s (oct)", str);
|
|
}
|
|
}
|
|
}
|
|
|
|
if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf("\n");
|
|
|
|
if(o170 > 0 || o270 > 0) {
|
|
int32_t sum = o170-o270;
|
|
if(sum > 0) {
|
|
listType = listType >= 1 ? listType : 1;
|
|
activeImportPower = sum;
|
|
} else {
|
|
listType = listType >= 2 ? listType : 2;
|
|
activeExportPower = sum * -1;
|
|
}
|
|
}
|
|
|
|
if(o181 > 0 || o182 > 0) {
|
|
activeImportCounter = (o181 + o182) / 1000.0;
|
|
listType = listType >= 3 ? listType : 3;
|
|
}
|
|
if(o281 > 0 || o282 > 0) {
|
|
activeExportCounter = (o281 + o282) / 1000.0;
|
|
listType = listType >= 3 ? listType : 3;
|
|
}
|
|
|
|
if((*data) == 0x09) {
|
|
data += (*(data+1))+2;
|
|
} 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;
|
|
}
|