mirror of
https://github.com/UtilitechAS/amsreader-firmware.git
synced 2026-05-01 05:59:24 +00:00
Added support for Iskraemeco IE.5 in Croatia (#1107)
* Added support for Croation Iskra * Temp removed meterid * Fixed HDLC block decoding * Fixed context length * Changing some stuff back * Change some stuff back * Final test * Added debugging * Updated selector for iskra dataformat * Added fake test frame
This commit is contained in:
48
frames/iskra_croatia.txt
Normal file
48
frames/iskra_croatia.txt
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
They actually use multiple frames, so this is a "fake" frame combining the two into one, but without checksum fields.
|
||||||
|
|
||||||
|
7E
|
||||||
|
A0 BD
|
||||||
|
CF 02 23 03 00 00
|
||||||
|
E6 E7 00
|
||||||
|
0F 00 03 46 3B
|
||||||
|
0C 07 E9 0C 13 05 17 37 28 00 FF C4 00
|
||||||
|
|
||||||
|
02 21
|
||||||
|
09 08 39 32 30 32 39 36 39 31
|
||||||
|
09 04 17 37 28 00
|
||||||
|
09 05 07 E9 0C 13 05
|
||||||
|
06 00 6C 28 5A
|
||||||
|
06 00 4B 76 1A
|
||||||
|
06 00 20 B2 40
|
||||||
|
06 00 58 68 AA
|
||||||
|
06 00 57 A1 62
|
||||||
|
06 00 00 C7 48
|
||||||
|
06 00 17 EE D7
|
||||||
|
06 00 12 F5 5C
|
||||||
|
06 00 00 D9 6A
|
||||||
|
06 00 15 36 84
|
||||||
|
06 00 00 01 7E
|
||||||
|
06 00 00 00 00
|
||||||
|
12 03 79
|
||||||
|
06 00 00 00 7F
|
||||||
|
06 00 00 00 BD
|
||||||
|
06 00 00 00 41
|
||||||
|
06 00 00 00 00
|
||||||
|
06 00 00 00 00
|
||||||
|
06 00 00 00 00
|
||||||
|
12 09 54
|
||||||
|
12 09 35
|
||||||
|
12 09 49
|
||||||
|
12 00 37
|
||||||
|
12 00 59
|
||||||
|
12 00 4D
|
||||||
|
06 00 00 43 62
|
||||||
|
01 01
|
||||||
|
12 24 B8
|
||||||
|
01 01
|
||||||
|
12 24 B8
|
||||||
|
01 01
|
||||||
|
12 24 B8
|
||||||
|
03 01
|
||||||
|
|
||||||
|
00 00 7E
|
||||||
@@ -69,7 +69,12 @@ int8_t HDLCParser::parse(uint8_t *d, DataParserContext &ctx) {
|
|||||||
|
|
||||||
if(buf == NULL) return DATA_PARSE_FAIL;
|
if(buf == NULL) return DATA_PARSE_FAIL;
|
||||||
|
|
||||||
memcpy(buf + pos, ptr+3, ctx.length); // +3 to skip LLC
|
if((*ptr) == DATA_TAG_LLC) {
|
||||||
|
ptr += 3; // Skip LLC
|
||||||
|
ctx.length -= 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(buf + pos, ptr, ctx.length);
|
||||||
pos += ctx.length;
|
pos += ctx.length;
|
||||||
|
|
||||||
lastSequenceNumber++;
|
lastSequenceNumber++;
|
||||||
@@ -78,7 +83,12 @@ int8_t HDLCParser::parse(uint8_t *d, DataParserContext &ctx) {
|
|||||||
lastSequenceNumber = 0;
|
lastSequenceNumber = 0;
|
||||||
if(buf == NULL) return DATA_PARSE_FAIL;
|
if(buf == NULL) return DATA_PARSE_FAIL;
|
||||||
|
|
||||||
memcpy(buf + pos, ptr+3, ctx.length); // +3 to skip LLC
|
if((*ptr) == DATA_TAG_LLC) {
|
||||||
|
ptr += 3; // Skip LLC
|
||||||
|
ctx.length -= 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(buf + pos, ptr, ctx.length);
|
||||||
pos += ctx.length;
|
pos += ctx.length;
|
||||||
|
|
||||||
memcpy((uint8_t *) d, buf, pos);
|
memcpy((uint8_t *) d, buf, pos);
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ IEC6205675::IEC6205675(const char* d, Timezone* tz, uint8_t useMeterType, MeterC
|
|||||||
this->listId = listId;
|
this->listId = listId;
|
||||||
meterType = AmsTypeKaifa;
|
meterType = AmsTypeKaifa;
|
||||||
|
|
||||||
int idx = 0;
|
uint8_t idx = 0;
|
||||||
data = getCosemDataAt(idx, ((char *) (d)));
|
data = getCosemDataAt(idx, ((char *) (d)));
|
||||||
idx+=2;
|
idx+=2;
|
||||||
if(data->base.length == 0x0D || data->base.length == 0x12) {
|
if(data->base.length == 0x0D || data->base.length == 0x12) {
|
||||||
@@ -141,7 +141,7 @@ IEC6205675::IEC6205675(const char* d, Timezone* tz, uint8_t useMeterType, MeterC
|
|||||||
this->listId = listId;
|
this->listId = listId;
|
||||||
meterType = AmsTypeIskra;
|
meterType = AmsTypeIskra;
|
||||||
|
|
||||||
int idx = 0;
|
uint8_t idx = 0;
|
||||||
data = getCosemDataAt(idx++, ((char *) (d)));
|
data = getCosemDataAt(idx++, ((char *) (d)));
|
||||||
if(data->base.length == 0x12) {
|
if(data->base.length == 0x12) {
|
||||||
apply(state);
|
apply(state);
|
||||||
@@ -558,54 +558,157 @@ IEC6205675::IEC6205675(const char* d, Timezone* tz, uint8_t useMeterType, MeterC
|
|||||||
}
|
}
|
||||||
} else if(useMeterType == AmsTypeIskra && data->base.type == CosemTypeOctetString) { // Iskra special case
|
} else if(useMeterType == AmsTypeIskra && data->base.type == CosemTypeOctetString) { // Iskra special case
|
||||||
meterType = AmsTypeIskra;
|
meterType = AmsTypeIskra;
|
||||||
uint8_t idx = 5;
|
|
||||||
|
|
||||||
data = getCosemDataAt(idx++, ((char *) (d)));
|
uint8_t idx = 0;
|
||||||
if(data != NULL) {
|
data = getCosemDataAt(idx, ((char *) (d)));
|
||||||
|
if(data->base.length == 0x21) {
|
||||||
|
idx = 4;
|
||||||
|
|
||||||
|
// 1.8.0
|
||||||
|
data = getCosemDataAt(idx++, ((char *) (d)));
|
||||||
activeImportCounter = ntohl(data->dlu.data) / 1000.0;
|
activeImportCounter = ntohl(data->dlu.data) / 1000.0;
|
||||||
}
|
|
||||||
|
// 1.8.1
|
||||||
data = getCosemDataAt(idx++, ((char *) (d)));
|
// 1.8.2
|
||||||
if(data != NULL) {
|
idx += 2;
|
||||||
|
|
||||||
|
// 2.8.0
|
||||||
|
data = getCosemDataAt(idx++, ((char *) (d)));
|
||||||
activeExportCounter = ntohl(data->dlu.data) / 1000.0;
|
activeExportCounter = ntohl(data->dlu.data) / 1000.0;
|
||||||
}
|
|
||||||
|
|
||||||
data = getCosemDataAt(idx++, ((char *) (d)));
|
|
||||||
if(data != NULL) {
|
|
||||||
reactiveImportCounter = ntohl(data->dlu.data) / 1000.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
data = getCosemDataAt(idx++, ((char *) (d)));
|
|
||||||
if(data != NULL) {
|
|
||||||
reactiveExportCounter = ntohl(data->dlu.data) / 1000.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
data = getCosemDataAt(idx++, ((char *) (d)));
|
// 2.8.1
|
||||||
if(data != NULL) {
|
// 2.8.2
|
||||||
|
idx += 2;
|
||||||
|
|
||||||
|
// 5.8.0
|
||||||
|
// 6.8.0
|
||||||
|
// 7.8.0
|
||||||
|
// 8.8.0
|
||||||
|
idx += 4;
|
||||||
|
|
||||||
|
// 1.7.0
|
||||||
|
data = getCosemDataAt(idx++, ((char *) (d)));
|
||||||
activeImportPower = ntohl(data->dlu.data);
|
activeImportPower = ntohl(data->dlu.data);
|
||||||
}
|
|
||||||
|
|
||||||
data = getCosemDataAt(idx++, ((char *) (d)));
|
// 2.7.0
|
||||||
if(data != NULL) {
|
data = getCosemDataAt(idx++, ((char *) (d)));
|
||||||
activeExportPower = ntohl(data->dlu.data);
|
activeExportPower = ntohl(data->dlu.data);
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t str_len = 0;
|
// 13.7.0
|
||||||
str_len = getString(AMS_OBIS_UNKNOWN_1, sizeof(AMS_OBIS_UNKNOWN_1), ((char *) (d)), str);
|
data = getCosemDataAt(idx++, ((char *) (d)));
|
||||||
if(str_len > 0) {
|
powerFactor= ntohl(data->dlu.data) / 1000.0;
|
||||||
meterId = String(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
listType = 3;
|
// 21.7.0
|
||||||
lastUpdateMillis = millis64();
|
data = getCosemDataAt(idx++, ((char *) (d)));
|
||||||
|
l1activeImportPower = ntohl(data->dlu.data);
|
||||||
|
|
||||||
|
// 41.7.0
|
||||||
|
data = getCosemDataAt(idx++, ((char *) (d)));
|
||||||
|
l2activeImportPower = ntohl(data->dlu.data);
|
||||||
|
|
||||||
|
// 61.7.0
|
||||||
|
data = getCosemDataAt(idx++, ((char *) (d)));
|
||||||
|
l3activeImportPower = ntohl(data->dlu.data);
|
||||||
|
|
||||||
|
// 22.7.0
|
||||||
|
data = getCosemDataAt(idx++, ((char *) (d)));
|
||||||
|
l1activeExportPower = ntohl(data->dlu.data);
|
||||||
|
|
||||||
|
// 42.7.0
|
||||||
|
data = getCosemDataAt(idx++, ((char *) (d)));
|
||||||
|
l2activeExportPower = ntohl(data->dlu.data);
|
||||||
|
|
||||||
|
// 62.7.0
|
||||||
|
data = getCosemDataAt(idx++, ((char *) (d)));
|
||||||
|
l3activeExportPower = ntohl(data->dlu.data);
|
||||||
|
|
||||||
|
// 32.7.0
|
||||||
|
data = getCosemDataAt(idx++, ((char *) (d)));
|
||||||
|
l1voltage = ntohs(data->lu.data) / 10.0;
|
||||||
|
|
||||||
|
// 52.7.0
|
||||||
|
data = getCosemDataAt(idx++, ((char *) (d)));
|
||||||
|
l2voltage = ntohs(data->lu.data) / 10.0;
|
||||||
|
|
||||||
|
// 72.7.0
|
||||||
|
data = getCosemDataAt(idx++, ((char *) (d)));
|
||||||
|
l3voltage = ntohs(data->lu.data) / 10.0;
|
||||||
|
|
||||||
|
// 31.7.0
|
||||||
|
data = getCosemDataAt(idx++, ((char *) (d)));
|
||||||
|
l1current = ntohs(data->lu.data) / 100.0;
|
||||||
|
|
||||||
|
// 51.7.0
|
||||||
|
data = getCosemDataAt(idx++, ((char *) (d)));
|
||||||
|
l2current = ntohs(data->lu.data) / 100.0;
|
||||||
|
|
||||||
|
// 71.7.0
|
||||||
|
data = getCosemDataAt(idx++, ((char *) (d)));
|
||||||
|
l3current = ntohs(data->lu.data) / 100.0;
|
||||||
|
|
||||||
|
listType = 4;
|
||||||
|
lastUpdateMillis = millis64();
|
||||||
|
} else {
|
||||||
|
idx = 5;
|
||||||
|
|
||||||
|
data = getCosemDataAt(idx++, ((char *) (d)));
|
||||||
|
if(data != NULL) {
|
||||||
|
activeImportCounter = ntohl(data->dlu.data) / 1000.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
data = getCosemDataAt(idx++, ((char *) (d)));
|
||||||
|
if(data != NULL) {
|
||||||
|
activeExportCounter = ntohl(data->dlu.data) / 1000.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
data = getCosemDataAt(idx++, ((char *) (d)));
|
||||||
|
if(data != NULL) {
|
||||||
|
reactiveImportCounter = ntohl(data->dlu.data) / 1000.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
data = getCosemDataAt(idx++, ((char *) (d)));
|
||||||
|
if(data != NULL) {
|
||||||
|
reactiveExportCounter = ntohl(data->dlu.data) / 1000.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
data = getCosemDataAt(idx++, ((char *) (d)));
|
||||||
|
if(data != NULL) {
|
||||||
|
activeImportPower = ntohl(data->dlu.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
data = getCosemDataAt(idx++, ((char *) (d)));
|
||||||
|
if(data != NULL) {
|
||||||
|
activeExportPower = ntohl(data->dlu.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t str_len = 0;
|
||||||
|
str_len = getString(AMS_OBIS_UNKNOWN_1, sizeof(AMS_OBIS_UNKNOWN_1), ((char *) (d)), str);
|
||||||
|
if(str_len > 0) {
|
||||||
|
meterId = String(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
listType = 4;
|
||||||
|
lastUpdateMillis = millis64();
|
||||||
|
}
|
||||||
} else if(useMeterType == AmsTypeUnknown) {
|
} else if(useMeterType == AmsTypeUnknown) {
|
||||||
uint8_t str_len = 0;
|
uint8_t idx = 1;
|
||||||
str_len = getString(AMS_OBIS_UNKNOWN_1, sizeof(AMS_OBIS_UNKNOWN_1), ((char *) (d)), str);
|
CosemData* d1 = getCosemDataAt(idx++, ((char *) (d)));
|
||||||
if(str_len > 0) {
|
CosemData* d2 = getCosemDataAt(idx++, ((char *) (d)));
|
||||||
|
CosemData* d3 = getCosemDataAt(idx++, ((char *) (d)));
|
||||||
|
|
||||||
|
if(d1->base.type == CosemTypeOctetString && d2->base.type == CosemTypeOctetString && d3->base.type == CosemTypeOctetString) {
|
||||||
meterType = AmsTypeIskra;
|
meterType = AmsTypeIskra;
|
||||||
meterId = String(str);
|
|
||||||
lastUpdateMillis = millis64();
|
lastUpdateMillis = millis64();
|
||||||
listType = 3;
|
listType = 3;
|
||||||
|
} else {
|
||||||
|
uint8_t str_len = 0;
|
||||||
|
str_len = getString(AMS_OBIS_UNKNOWN_1, sizeof(AMS_OBIS_UNKNOWN_1), ((char *) (d)), str);
|
||||||
|
if(str_len > 0) {
|
||||||
|
meterType = AmsTypeIskra;
|
||||||
|
meterId = String(str);
|
||||||
|
lastUpdateMillis = millis64();
|
||||||
|
listType = 3;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user