#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; }