mirror of
https://github.com/UtilitechAS/amsreader-firmware.git
synced 2026-04-18 01:16:35 +00:00
Fixed reading of numbers. Added support for newer Kaifa payload
This commit is contained in:
@@ -140,11 +140,13 @@ IEC6205675::IEC6205675(const char* d, uint8_t useMeterType, uint8_t distribution
|
|||||||
|
|
||||||
meterType = AmsTypeUnknown;
|
meterType = AmsTypeUnknown;
|
||||||
CosemData* version = findObis(AMS_OBIS_VERSION, sizeof(AMS_OBIS_VERSION), d);
|
CosemData* version = findObis(AMS_OBIS_VERSION, sizeof(AMS_OBIS_VERSION), d);
|
||||||
if(version != NULL && version->base.type == CosemTypeString) {
|
if(version != NULL && (version->base.type == CosemTypeString || version->base.type == CosemTypeOctetString)) {
|
||||||
if(memcmp(version->str.data, "AIDON", 5) == 0) {
|
if(memcmp(version->str.data, "AIDON", 5) == 0) {
|
||||||
meterType = AmsTypeAidon;
|
meterType = AmsTypeAidon;
|
||||||
} else if(memcmp(version->str.data, "Kamstrup", 8) == 0) {
|
} else if(memcmp(version->str.data, "Kamstrup", 8) == 0) {
|
||||||
meterType = AmsTypeKamstrup;
|
meterType = AmsTypeKamstrup;
|
||||||
|
} else if(memcmp(version->str.data, "KFM", 3) == 0) {
|
||||||
|
meterType = AmsTypeKaifa;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
version = getCosemDataAt(1, ((char *) (d)));
|
version = getCosemDataAt(1, ((char *) (d)));
|
||||||
@@ -315,7 +317,6 @@ IEC6205675::IEC6205675(const char* d, uint8_t useMeterType, uint8_t distribution
|
|||||||
l2current = l2current != 0 ? l2current / 10 : 0;
|
l2current = l2current != 0 ? l2current / 10 : 0;
|
||||||
l3current = l3current != 0 ? l3current / 10 : 0;
|
l3current = l3current != 0 ? l3current / 10 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if(meterType == AmsTypeSagemcom) {
|
} else if(meterType == AmsTypeSagemcom) {
|
||||||
CosemData* meterTs = getCosemDataAt(1, ((char *) (d)));
|
CosemData* meterTs = getCosemDataAt(1, ((char *) (d)));
|
||||||
if(meterTs != NULL) {
|
if(meterTs != NULL) {
|
||||||
@@ -337,6 +338,19 @@ IEC6205675::IEC6205675(const char* d, uint8_t useMeterType, uint8_t distribution
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if(meterType == AmsTypeKaifa) {
|
||||||
|
if(l1current != 0)
|
||||||
|
l1current /= 1000;
|
||||||
|
if(l2current != 0)
|
||||||
|
l2current /= 1000;
|
||||||
|
if(l3current != 0)
|
||||||
|
l3current /= 1000;
|
||||||
|
if(l1voltage != 0)
|
||||||
|
l1voltage /= 10;
|
||||||
|
if(l2voltage != 0)
|
||||||
|
l2voltage /= 10;
|
||||||
|
if(l3voltage != 0)
|
||||||
|
l3voltage /= 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
lastUpdateMillis = millis();
|
lastUpdateMillis = millis();
|
||||||
@@ -379,14 +393,17 @@ CosemData* IEC6205675::getCosemDataAt(uint8_t index, const char* ptr) {
|
|||||||
pos += 2 + item->base.length;
|
pos += 2 + item->base.length;
|
||||||
break;
|
break;
|
||||||
case CosemTypeLongSigned:
|
case CosemTypeLongSigned:
|
||||||
pos += 5;
|
|
||||||
break;
|
|
||||||
case CosemTypeLongUnsigned:
|
case CosemTypeLongUnsigned:
|
||||||
pos += 3;
|
pos += 3;
|
||||||
break;
|
break;
|
||||||
|
case CosemTypeDLongSigned:
|
||||||
case CosemTypeDLongUnsigned:
|
case CosemTypeDLongUnsigned:
|
||||||
pos += 5;
|
pos += 5;
|
||||||
break;
|
break;
|
||||||
|
case CosemTypeLong64Signed:
|
||||||
|
case CosemTypeLong64Unsigned:
|
||||||
|
pos += 9;
|
||||||
|
break;
|
||||||
case CosemTypeNull:
|
case CosemTypeNull:
|
||||||
pos += 1;
|
pos += 1;
|
||||||
break;
|
break;
|
||||||
@@ -424,14 +441,17 @@ CosemData* IEC6205675::findObis(uint8_t* obis, int matchlength, const char* ptr)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CosemTypeLongSigned:
|
case CosemTypeLongSigned:
|
||||||
pos += 5;
|
|
||||||
break;
|
|
||||||
case CosemTypeLongUnsigned:
|
case CosemTypeLongUnsigned:
|
||||||
pos += 3;
|
pos += 3;
|
||||||
break;
|
break;
|
||||||
|
case CosemTypeDLongSigned:
|
||||||
case CosemTypeDLongUnsigned:
|
case CosemTypeDLongUnsigned:
|
||||||
pos += 5;
|
pos += 5;
|
||||||
break;
|
break;
|
||||||
|
case CosemTypeLong64Signed:
|
||||||
|
case CosemTypeLong64Unsigned:
|
||||||
|
pos += 9;
|
||||||
|
break;
|
||||||
case CosemTypeNull:
|
case CosemTypeNull:
|
||||||
pos += 1;
|
pos += 1;
|
||||||
break;
|
break;
|
||||||
@@ -470,22 +490,40 @@ double IEC6205675::getNumber(CosemData* item) {
|
|||||||
double ret = 0.0;
|
double ret = 0.0;
|
||||||
char* pos = ((char*) item);
|
char* pos = ((char*) item);
|
||||||
switch(item->base.type) {
|
switch(item->base.type) {
|
||||||
|
case CosemTypeLongSigned: {
|
||||||
|
int16_t i16 = ntohs(item->ls.data);
|
||||||
|
ret = i16;
|
||||||
|
pos += 3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case CosemTypeLongUnsigned: {
|
case CosemTypeLongUnsigned: {
|
||||||
uint16_t u16 = ntohs(item->lu.data);
|
uint16_t u16 = ntohs(item->lu.data);
|
||||||
ret = u16;
|
ret = u16;
|
||||||
pos += 3;
|
pos += 3;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case CosemTypeDLongSigned: {
|
||||||
|
int32_t i32 = ntohl(item->dlu.data);
|
||||||
|
ret = i32;
|
||||||
|
pos += 5;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case CosemTypeDLongUnsigned: {
|
case CosemTypeDLongUnsigned: {
|
||||||
uint32_t u32 = ntohl(item->dlu.data);
|
uint32_t u32 = ntohl(item->dlu.data);
|
||||||
ret = u32;
|
ret = u32;
|
||||||
pos += 5;
|
pos += 5;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CosemTypeLongSigned: {
|
case CosemTypeLong64Signed: {
|
||||||
int16_t i16 = ntohs(item->ls.data);
|
int64_t i64 = ntohll(item->l64s.data);
|
||||||
ret = i16;
|
ret = i64;
|
||||||
pos += 3;
|
pos += 9;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CosemTypeLong64Unsigned: {
|
||||||
|
uint64_t u64 = ntohll(item->l64u.data);
|
||||||
|
ret = u64;
|
||||||
|
pos += 9;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ private:
|
|||||||
time_t getTimestamp(uint8_t* obis, int matchlength, const char* ptr);
|
time_t getTimestamp(uint8_t* obis, int matchlength, const char* ptr);
|
||||||
time_t getTimestamp(CosemDateTime timestamp);
|
time_t getTimestamp(CosemDateTime timestamp);
|
||||||
|
|
||||||
uint8_t AMS_OBIS_VERSION[6] = { 1, 1, 0, 2, 129, 255 };
|
uint8_t AMS_OBIS_VERSION[4] = { 0, 2, 129, 255 };
|
||||||
uint8_t AMS_OBIS_METER_MODEL[4] = { 96, 1, 1, 255 };
|
uint8_t AMS_OBIS_METER_MODEL[4] = { 96, 1, 1, 255 };
|
||||||
uint8_t AMS_OBIS_METER_MODEL_2[4] = { 96, 1, 7, 255 };
|
uint8_t AMS_OBIS_METER_MODEL_2[4] = { 96, 1, 7, 255 };
|
||||||
uint8_t AMS_OBIS_METER_ID[4] = { 96, 1, 0, 255 };
|
uint8_t AMS_OBIS_METER_ID[4] = { 96, 1, 0, 255 };
|
||||||
|
|||||||
@@ -287,3 +287,7 @@ uint8_t mbusChecksum(const uint8_t* p, int len) {
|
|||||||
ret += *p++;
|
ret += *p++;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64_t ntohll(uint64_t x) {
|
||||||
|
return (((uint64_t)ntohl((uint32_t)x)) << 32) + ntohl(x >> 32);
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "Arduino.h"
|
#include "Arduino.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include "lwip/def.h"
|
||||||
|
|
||||||
#define HDLC_FLAG 0x7E
|
#define HDLC_FLAG 0x7E
|
||||||
#define HDLC_BOUNDRY_FLAG_MISSING -1
|
#define HDLC_BOUNDRY_FLAG_MISSING -1
|
||||||
@@ -79,9 +80,12 @@ enum CosemType {
|
|||||||
CosemTypeStructure = 0x02,
|
CosemTypeStructure = 0x02,
|
||||||
CosemTypeOctetString = 0x09,
|
CosemTypeOctetString = 0x09,
|
||||||
CosemTypeString = 0x0A,
|
CosemTypeString = 0x0A,
|
||||||
|
CosemTypeDLongSigned = 0x05,
|
||||||
CosemTypeDLongUnsigned = 0x06,
|
CosemTypeDLongUnsigned = 0x06,
|
||||||
CosemTypeLongSigned = 0x10,
|
CosemTypeLongSigned = 0x10,
|
||||||
CosemTypeLongUnsigned = 0x12,
|
CosemTypeLongUnsigned = 0x12,
|
||||||
|
CosemTypeLong64Signed = 0x14,
|
||||||
|
CosemTypeLong64Unsigned = 0x15,
|
||||||
CosemTypeDateTime = 0x19
|
CosemTypeDateTime = 0x19
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -96,19 +100,34 @@ struct CosemString {
|
|||||||
uint8_t data[];
|
uint8_t data[];
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct CosemLongSigned {
|
||||||
|
uint8_t type;
|
||||||
|
int16_t data;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
struct CosemLongUnsigned {
|
struct CosemLongUnsigned {
|
||||||
uint8_t type;
|
uint8_t type;
|
||||||
uint16_t data;
|
uint16_t data;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct CosemDLongSigned {
|
||||||
|
uint8_t type;
|
||||||
|
int32_t data;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
struct CosemDLongUnsigned {
|
struct CosemDLongUnsigned {
|
||||||
uint8_t type;
|
uint8_t type;
|
||||||
uint32_t data;
|
uint32_t data;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
struct CosemLongSigned {
|
struct CosemLong64Signed {
|
||||||
uint8_t type;
|
uint8_t type;
|
||||||
int16_t data;
|
int64_t data;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct CosemLong64Unsigned {
|
||||||
|
uint8_t type;
|
||||||
|
uint64_t data;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
struct CosemDateTime {
|
struct CosemDateTime {
|
||||||
@@ -129,9 +148,12 @@ typedef union {
|
|||||||
struct CosemBasic base;
|
struct CosemBasic base;
|
||||||
struct CosemString str;
|
struct CosemString str;
|
||||||
struct CosemString oct;
|
struct CosemString oct;
|
||||||
struct CosemLongUnsigned lu;
|
|
||||||
struct CosemDLongUnsigned dlu;
|
|
||||||
struct CosemLongSigned ls;
|
struct CosemLongSigned ls;
|
||||||
|
struct CosemLongUnsigned lu;
|
||||||
|
struct CosemDLongSigned dls;
|
||||||
|
struct CosemDLongUnsigned dlu;
|
||||||
|
struct CosemLong64Signed l64s;
|
||||||
|
struct CosemLong64Unsigned l64u;
|
||||||
struct CosemDateTime dt;
|
struct CosemDateTime dt;
|
||||||
} CosemData;
|
} CosemData;
|
||||||
|
|
||||||
@@ -140,4 +162,6 @@ int HDLC_validate(const uint8_t* d, int len, HDLCConfig* config, CosemDateTime*
|
|||||||
|
|
||||||
uint8_t mbusChecksum(const uint8_t* p, int len);
|
uint8_t mbusChecksum(const uint8_t* p, int len);
|
||||||
|
|
||||||
|
uint64_t ntohll(uint64_t x);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user