diff --git a/src/IEC6205675.cpp b/src/IEC6205675.cpp index 619dbf08..f970d29b 100644 --- a/src/IEC6205675.cpp +++ b/src/IEC6205675.cpp @@ -140,11 +140,13 @@ IEC6205675::IEC6205675(const char* d, uint8_t useMeterType, uint8_t distribution meterType = AmsTypeUnknown; 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) { meterType = AmsTypeAidon; } else if(memcmp(version->str.data, "Kamstrup", 8) == 0) { meterType = AmsTypeKamstrup; + } else if(memcmp(version->str.data, "KFM", 3) == 0) { + meterType = AmsTypeKaifa; } } else { version = getCosemDataAt(1, ((char *) (d))); @@ -319,7 +321,6 @@ IEC6205675::IEC6205675(const char* d, uint8_t useMeterType, uint8_t distribution l2current = l2current != 0 ? l2current / 10 : 0; l3current = l3current != 0 ? l3current / 10 : 0; } - } else if(meterType == AmsTypeSagemcom) { CosemData* meterTs = getCosemDataAt(1, ((char *) (d))); if(meterTs != NULL) { @@ -341,6 +342,19 @@ IEC6205675::IEC6205675(const char* d, uint8_t useMeterType, uint8_t distribution 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(); @@ -383,14 +397,17 @@ CosemData* IEC6205675::getCosemDataAt(uint8_t index, const char* ptr) { pos += 2 + item->base.length; break; case CosemTypeLongSigned: - pos += 5; - break; case CosemTypeLongUnsigned: pos += 3; break; + case CosemTypeDLongSigned: case CosemTypeDLongUnsigned: pos += 5; break; + case CosemTypeLong64Signed: + case CosemTypeLong64Unsigned: + pos += 9; + break; case CosemTypeNull: pos += 1; break; @@ -428,14 +445,17 @@ CosemData* IEC6205675::findObis(uint8_t* obis, int matchlength, const char* ptr) break; } case CosemTypeLongSigned: - pos += 5; - break; case CosemTypeLongUnsigned: pos += 3; break; + case CosemTypeDLongSigned: case CosemTypeDLongUnsigned: pos += 5; break; + case CosemTypeLong64Signed: + case CosemTypeLong64Unsigned: + pos += 9; + break; case CosemTypeNull: pos += 1; break; @@ -474,22 +494,40 @@ double IEC6205675::getNumber(CosemData* item) { double ret = 0.0; char* pos = ((char*) item); switch(item->base.type) { + case CosemTypeLongSigned: { + int16_t i16 = ntohs(item->ls.data); + ret = i16; + pos += 3; + break; + } case CosemTypeLongUnsigned: { uint16_t u16 = ntohs(item->lu.data); ret = u16; pos += 3; break; } + case CosemTypeDLongSigned: { + int32_t i32 = ntohl(item->dlu.data); + ret = i32; + pos += 5; + break; + } case CosemTypeDLongUnsigned: { uint32_t u32 = ntohl(item->dlu.data); ret = u32; pos += 5; break; } - case CosemTypeLongSigned: { - int16_t i16 = ntohs(item->ls.data); - ret = i16; - pos += 3; + case CosemTypeLong64Signed: { + int64_t i64 = ntohll(item->l64s.data); + ret = i64; + pos += 9; + break; + } + case CosemTypeLong64Unsigned: { + uint64_t u64 = ntohll(item->l64u.data); + ret = u64; + pos += 9; break; } } diff --git a/src/IEC6205675.h b/src/IEC6205675.h index 089da58c..dd573939 100644 --- a/src/IEC6205675.h +++ b/src/IEC6205675.h @@ -24,7 +24,7 @@ private: time_t getTimestamp(uint8_t* obis, int matchlength, const char* ptr); 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_2[4] = { 96, 1, 7, 255 }; uint8_t AMS_OBIS_METER_ID[4] = { 96, 1, 0, 255 }; diff --git a/src/ams/hdlc.cpp b/src/ams/hdlc.cpp index a609683d..d6168f14 100644 --- a/src/ams/hdlc.cpp +++ b/src/ams/hdlc.cpp @@ -287,3 +287,7 @@ uint8_t mbusChecksum(const uint8_t* p, int len) { ret += *p++; return ret; } + +uint64_t ntohll(uint64_t x) { + return (((uint64_t)ntohl((uint32_t)x)) << 32) + ntohl(x >> 32); +} \ No newline at end of file diff --git a/src/ams/hdlc.h b/src/ams/hdlc.h index ac4cf699..9783de9d 100644 --- a/src/ams/hdlc.h +++ b/src/ams/hdlc.h @@ -3,6 +3,7 @@ #include "Arduino.h" #include +#include "lwip/def.h" #define HDLC_FLAG 0x7E #define HDLC_BOUNDRY_FLAG_MISSING -1 @@ -79,9 +80,12 @@ enum CosemType { CosemTypeStructure = 0x02, CosemTypeOctetString = 0x09, CosemTypeString = 0x0A, + CosemTypeDLongSigned = 0x05, CosemTypeDLongUnsigned = 0x06, CosemTypeLongSigned = 0x10, CosemTypeLongUnsigned = 0x12, + CosemTypeLong64Signed = 0x14, + CosemTypeLong64Unsigned = 0x15, CosemTypeDateTime = 0x19 }; @@ -96,19 +100,34 @@ struct CosemString { uint8_t data[]; } __attribute__((packed)); +struct CosemLongSigned { + uint8_t type; + int16_t data; +} __attribute__((packed)); + struct CosemLongUnsigned { uint8_t type; uint16_t data; } __attribute__((packed)); +struct CosemDLongSigned { + uint8_t type; + int32_t data; +} __attribute__((packed)); + struct CosemDLongUnsigned { uint8_t type; uint32_t data; } __attribute__((packed)); -struct CosemLongSigned { +struct CosemLong64Signed { uint8_t type; - int16_t data; + int64_t data; +} __attribute__((packed)); + +struct CosemLong64Unsigned { + uint8_t type; + uint64_t data; } __attribute__((packed)); struct CosemDateTime { @@ -129,9 +148,12 @@ typedef union { struct CosemBasic base; struct CosemString str; struct CosemString oct; - struct CosemLongUnsigned lu; - struct CosemDLongUnsigned dlu; struct CosemLongSigned ls; + struct CosemLongUnsigned lu; + struct CosemDLongSigned dls; + struct CosemDLongUnsigned dlu; + struct CosemLong64Signed l64s; + struct CosemLong64Unsigned l64u; struct CosemDateTime dt; } 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); +uint64_t ntohll(uint64_t x); + #endif diff --git a/src/mqtt/RawMqttHandler.cpp b/src/mqtt/RawMqttHandler.cpp index 0dd29156..3843deb3 100644 --- a/src/mqtt/RawMqttHandler.cpp +++ b/src/mqtt/RawMqttHandler.cpp @@ -214,6 +214,7 @@ bool RawMqttHandler::publishSystem(HwTools* hw) { if(vcc > 0) { mqtt->publish(topic + "/vcc", String(vcc, 2)); } + mqtt->publish(topic + "/mem", String(ESP.getFreeHeap())); mqtt->publish(topic + "/rssi", String(hw->getWifiRssi())); if(hw->getTemperature() > -85) { mqtt->publish(topic + "/temperature", String(hw->getTemperature(), 2)); diff --git a/web/domoticz.html b/web/domoticz.html index ce333eb9..428e48e0 100644 --- a/web/domoticz.html +++ b/web/domoticz.html @@ -24,13 +24,13 @@
- Voltage L1 IDX + Voltage L2 IDX
- Voltage L1 IDX + Voltage L3 IDX