Check for scaling and use if available

This commit is contained in:
Gunnar Skjold 2021-12-10 18:46:57 +01:00
parent 7da617e8c2
commit ebdc357a47
3 changed files with 132 additions and 109 deletions

30
frames/Aidon-Sweden.raw Normal file
View File

@ -0,0 +1,30 @@
7E A2 43 41 08 83 13 85 EB E6 E7 00 0F 40 00 00 00 00
01 1B
02 02 09 06 00 00 01 00 00 FF 09 0C 07 E5 0C 0A 05 10 39 00 FF 80 00 FF
02 03 09 06 01 00 01 07 00 FF 06 00 00 07 E5 02 02 0F 00 16 1B
02 03 09 06 01 00 02 07 00 FF 06 00 00 00 00 02 02 0F 00 16 1B
02 03 09 06 01 00 03 07 00 FF 06 00 00 00 00 02 02 0F 00 16 1D
02 03 09 06 01 00 04 07 00 FF 06 00 00 02 48 02 02 0F 00 16 1D
02 03 09 06 01 00 1F 07 00 FF 10 00 09 02 02 0F FF 16 21
02 03 09 06 01 00 33 07 00 FF 10 00 25 02 02 0F FF 16 21
02 03 09 06 01 00 47 07 00 FF 10 00 2E 02 02 0F FF 16 21
02 03 09 06 01 00 20 07 00 FF 12 08 E3 02 02 0F FF 16 23
02 03 09 06 01 00 34 07 00 FF 12 08 D8 02 02 0F FF 16 23
02 03 09 06 01 00 48 07 00 FF 12 08 DF 02 02 0F FF 16 23
02 03 09 06 01 00 15 07 00 FF 06 00 00 00 D5 02 02 0F 00 16 1B
02 03 09 06 01 00 16 07 00 FF 06 00 00 00 00 02 02 0F 00 16 1B
02 03 09 06 01 00 17 07 00 FF 06 00 00 00 00 02 02 0F 00 16 1D
02 03 09 06 01 00 18 07 00 FF 06 00 00 00 36 02 02 0F 00 16 1D
02 03 09 06 01 00 29 07 00 FF 06 00 00 03 0C 02 02 0F 00 16 1B
02 03 09 06 01 00 2A 07 00 FF 06 00 00 00 00 02 02 0F 00 16 1B
02 03 09 06 01 00 2B 07 00 FF 06 00 00 01 21 02 02 0F 00 16 1D
02 03 09 06 01 00 2C 07 00 FF 06 00 00 00 00 02 02 0F 00 16 1D
02 03 09 06 01 00 3D 07 00 FF 06 00 00 03 F9 02 02 0F 00 16 1B
02 03 09 06 01 00 3E 07 00 FF 06 00 00 00 00 02 02 0F 00 16 1B
02 03 09 06 01 00 3F 07 00 FF 06 00 00 00 00 02 02 0F 00 16 1D
02 03 09 06 01 00 40 07 00 FF 06 00 00 00 E9 02 02 0F 00 16 1D
02 03 09 06 01 00 01 08 00 FF 06 03 C2 5A 64 02 02 0F 00 16 1E
02 03 09 06 01 00 02 08 00 FF 06 00 00 00 00 02 02 0F 00 16 1E
02 03 09 06 01 00 03 08 00 FF 06 00 04 5D 06 02 02 0F 00 16 20
02 03 09 06 01 00 04 08 00 FF 06 00 B4 9D 89 02 02 0F 00 16 20
1C 90 7E

View File

@ -3,14 +3,14 @@
#include "Timezone.h" #include "Timezone.h"
IEC6205675::IEC6205675(const char* d, uint8_t useMeterType, CosemDateTime packageTimestamp) { IEC6205675::IEC6205675(const char* d, uint8_t useMeterType, CosemDateTime packageTimestamp) {
uint32_t u32; uint32_t ui;
int32_t s32; double val;
char str[64]; char str[64];
this->packageTimestamp = getTimestamp(packageTimestamp); this->packageTimestamp = getTimestamp(packageTimestamp);
u32 = getUnsignedNumber(AMS_OBIS_ACTIVE_IMPORT, sizeof(AMS_OBIS_ACTIVE_IMPORT), ((char *) (d))); ui = getNumber(AMS_OBIS_ACTIVE_IMPORT, sizeof(AMS_OBIS_ACTIVE_IMPORT), ((char *) (d)));
if(u32 == 0xFFFFFFFF) { if(ui == 0xFFFFFFFF) {
CosemData* data = getCosemDataAt(1, ((char *) (d))); CosemData* data = getCosemDataAt(1, ((char *) (d)));
// Kaifa special case... // Kaifa special case...
@ -124,7 +124,7 @@ IEC6205675::IEC6205675(const char* d, uint8_t useMeterType, CosemDateTime packag
// Kaifa end // Kaifa end
} else { } else {
listType = 1; listType = 1;
activeImportPower = u32; activeImportPower = ui;
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);
@ -151,119 +151,95 @@ IEC6205675::IEC6205675(const char* d, uint8_t useMeterType, CosemDateTime packag
this->packageTimestamp = this->packageTimestamp > 0 ? tz.toUTC(this->packageTimestamp) : 0; this->packageTimestamp = this->packageTimestamp > 0 ? tz.toUTC(this->packageTimestamp) : 0;
} }
u32 = getString(AMS_OBIS_VERSION, sizeof(AMS_OBIS_VERSION), ((char *) (d)), str); ui = getString(AMS_OBIS_VERSION, sizeof(AMS_OBIS_VERSION), ((char *) (d)), str);
if(u32 > 0) { if(ui > 0) {
listId = String(str); listId = String(str);
} }
u32 = getUnsignedNumber(AMS_OBIS_ACTIVE_EXPORT, sizeof(AMS_OBIS_ACTIVE_EXPORT), ((char *) (d))); ui = getNumber(AMS_OBIS_ACTIVE_EXPORT, sizeof(AMS_OBIS_ACTIVE_EXPORT), ((char *) (d)));
if(u32 != 0xFFFFFFFF) { if(ui != 0xFFFFFFFF) {
activeExportPower = u32; activeExportPower = ui;
} }
u32 = getUnsignedNumber(AMS_OBIS_REACTIVE_IMPORT, sizeof(AMS_OBIS_REACTIVE_IMPORT), ((char *) (d))); ui = getNumber(AMS_OBIS_REACTIVE_IMPORT, sizeof(AMS_OBIS_REACTIVE_IMPORT), ((char *) (d)));
if(u32 != 0xFFFFFFFF) { if(ui != 0xFFFFFFFF) {
reactiveImportPower = u32; reactiveImportPower = ui;
} }
u32 = getUnsignedNumber(AMS_OBIS_REACTIVE_EXPORT, sizeof(AMS_OBIS_REACTIVE_EXPORT), ((char *) (d))); ui = getNumber(AMS_OBIS_REACTIVE_EXPORT, sizeof(AMS_OBIS_REACTIVE_EXPORT), ((char *) (d)));
if(u32 != 0xFFFFFFFF) { if(ui != 0xFFFFFFFF) {
reactiveExportPower = u32; reactiveExportPower = ui;
} }
u32 = getUnsignedNumber(AMS_OBIS_VOLTAGE_L1, sizeof(AMS_OBIS_VOLTAGE_L1), ((char *) (d))); val = getNumber(AMS_OBIS_VOLTAGE_L1, sizeof(AMS_OBIS_VOLTAGE_L1), ((char *) (d)));
if(u32 != 0xFFFFFFFF) { if(val != 0xFFFFFFFF) {
listType = 2; listType = 2;
l1voltage = u32; l1voltage = val;
} }
u32 = getUnsignedNumber(AMS_OBIS_VOLTAGE_L2, sizeof(AMS_OBIS_VOLTAGE_L2), ((char *) (d))); val = getNumber(AMS_OBIS_VOLTAGE_L2, sizeof(AMS_OBIS_VOLTAGE_L2), ((char *) (d)));
if(u32 != 0xFFFFFFFF) { if(val != 0xFFFFFFFF) {
listType = 2; listType = 2;
l2voltage = u32; l2voltage = val;
} }
u32 = getUnsignedNumber(AMS_OBIS_VOLTAGE_L3, sizeof(AMS_OBIS_VOLTAGE_L3), ((char *) (d))); val = getNumber(AMS_OBIS_VOLTAGE_L3, sizeof(AMS_OBIS_VOLTAGE_L3), ((char *) (d)));
if(u32 != 0xFFFFFFFF) { if(val != 0xFFFFFFFF) {
listType = 2; listType = 2;
l3voltage = u32; l3voltage = val;
} }
s32 = getSignedNumber(AMS_OBIS_CURRENT_L1, sizeof(AMS_OBIS_CURRENT_L1), ((char *) (d))); val = getNumber(AMS_OBIS_CURRENT_L1, sizeof(AMS_OBIS_CURRENT_L1), ((char *) (d)));
if(s32 != 0xFFFFFFFF) { if(val != 0xFFFFFFFF) {
listType = 2; listType = 2;
l1current = s32; l1current = val;
} }
s32 = getSignedNumber(AMS_OBIS_CURRENT_L2, sizeof(AMS_OBIS_CURRENT_L2), ((char *) (d))); val = getNumber(AMS_OBIS_CURRENT_L2, sizeof(AMS_OBIS_CURRENT_L2), ((char *) (d)));
if(s32 != 0xFFFFFFFF) { if(val != 0xFFFFFFFF) {
listType = 2; listType = 2;
l2current = s32; l2current = val;
} }
s32 = getSignedNumber(AMS_OBIS_CURRENT_L3, sizeof(AMS_OBIS_CURRENT_L3), ((char *) (d))); val = getNumber(AMS_OBIS_CURRENT_L3, sizeof(AMS_OBIS_CURRENT_L3), ((char *) (d)));
if(s32 != 0xFFFFFFFF) { if(val != 0xFFFFFFFF) {
listType = 2; listType = 2;
l3current = s32; l3current = val;
} }
if(listType == 2) { val = getNumber(AMS_OBIS_ACTIVE_IMPORT_COUNT, sizeof(AMS_OBIS_ACTIVE_IMPORT_COUNT), ((char *) (d)));
int vdiv = 1; if(val != 0xFFFFFFFF) {
int voltage = l1voltage == 0 ? l2voltage == 0 ? l3voltage == 0 ? 0 : l3voltage : l2voltage : l1voltage;
while(voltage > 1000) {
vdiv *= 10;
voltage /= 10;
}
l1voltage = l1voltage != 0 ? l1voltage / vdiv : 0;
l2voltage = l2voltage != 0 ? l2voltage / vdiv : 0;
l3voltage = l3voltage != 0 ? l3voltage / vdiv : 0;
int adiv = 1;
int watt = (l1voltage * l1current) + (l2voltage * l2current) + (l3voltage * l3current);
while(activeImportPower > 0 && watt / activeImportPower > 2) {
adiv *= 10;
watt /= 10;
}
l1current = l1current != 0 ? l1current / adiv : 0;
l2current = l2current != 0 ? l2current / adiv : 0;
l3current = l3current != 0 ? l3current / adiv : 0;
}
u32 = getUnsignedNumber(AMS_OBIS_ACTIVE_IMPORT_COUNT, sizeof(AMS_OBIS_ACTIVE_IMPORT_COUNT), ((char *) (d)));
if(u32 != 0xFFFFFFFF) {
listType = 3; listType = 3;
activeImportCounter = u32 / 100.0; activeImportCounter = val / 1000.0;
} }
u32 = getUnsignedNumber(AMS_OBIS_ACTIVE_EXPORT_COUNT, sizeof(AMS_OBIS_ACTIVE_EXPORT_COUNT), ((char *) (d))); val = getNumber(AMS_OBIS_ACTIVE_EXPORT_COUNT, sizeof(AMS_OBIS_ACTIVE_EXPORT_COUNT), ((char *) (d)));
if(u32 != 0xFFFFFFFF) { if(val != 0xFFFFFFFF) {
listType = 3; listType = 3;
activeExportCounter = u32 / 100.0; activeExportCounter = val / 1000.0;
} }
u32 = getUnsignedNumber(AMS_OBIS_REACTIVE_IMPORT_COUNT, sizeof(AMS_OBIS_REACTIVE_IMPORT_COUNT), ((char *) (d))); val = getNumber(AMS_OBIS_REACTIVE_IMPORT_COUNT, sizeof(AMS_OBIS_REACTIVE_IMPORT_COUNT), ((char *) (d)));
if(u32 != 0xFFFFFFFF) { if(val != 0xFFFFFFFF) {
listType = 3; listType = 3;
reactiveImportCounter = u32 / 100.0; reactiveImportCounter = val / 1000.0;
} }
u32 = getUnsignedNumber(AMS_OBIS_REACTIVE_EXPORT_COUNT, sizeof(AMS_OBIS_REACTIVE_EXPORT_COUNT), ((char *) (d))); val = getNumber(AMS_OBIS_REACTIVE_EXPORT_COUNT, sizeof(AMS_OBIS_REACTIVE_EXPORT_COUNT), ((char *) (d)));
if(u32 != 0xFFFFFFFF) { if(val != 0xFFFFFFFF) {
listType = 3; listType = 3;
reactiveExportCounter = u32 / 100.0; reactiveExportCounter = val / 1000.0;
} }
u32 = getString(AMS_OBIS_METER_MODEL, sizeof(AMS_OBIS_METER_MODEL), ((char *) (d)), str); ui = getString(AMS_OBIS_METER_MODEL, sizeof(AMS_OBIS_METER_MODEL), ((char *) (d)), str);
if(u32 > 0) { if(ui > 0) {
meterModel = String(str); meterModel = String(str);
} else { } else {
u32 = getString(AMS_OBIS_METER_MODEL_2, sizeof(AMS_OBIS_METER_MODEL_2), ((char *) (d)), str); ui = getString(AMS_OBIS_METER_MODEL_2, sizeof(AMS_OBIS_METER_MODEL_2), ((char *) (d)), str);
if(u32 > 0) { if(ui > 0) {
meterModel = String(str); meterModel = String(str);
} }
} }
u32 = getString(AMS_OBIS_METER_ID, sizeof(AMS_OBIS_METER_ID), ((char *) (d)), str); ui = getString(AMS_OBIS_METER_ID, sizeof(AMS_OBIS_METER_ID), ((char *) (d)), str);
if(u32 > 0) { if(ui > 0) {
meterId = String(str); meterId = String(str);
} else { } else {
u32 = getString(AMS_OBIS_METER_ID_2, sizeof(AMS_OBIS_METER_ID_2), ((char *) (d)), str); ui = getString(AMS_OBIS_METER_ID_2, sizeof(AMS_OBIS_METER_ID_2), ((char *) (d)), str);
if(u32 > 0) { if(ui > 0) {
meterId = String(str); meterId = String(str);
} }
} }
@ -279,21 +255,35 @@ IEC6205675::IEC6205675(const char* d, uint8_t useMeterType, CosemDateTime packag
} }
} }
u32 = getUnsignedNumber(AMS_OBIS_POWER_FACTOR, sizeof(AMS_OBIS_POWER_FACTOR), ((char *) (d))); val = getNumber(AMS_OBIS_POWER_FACTOR, sizeof(AMS_OBIS_POWER_FACTOR), ((char *) (d)));
if(u32 != 0xFFFFFFFF) { if(val != 0xFFFFFFFF) {
powerFactor = u32 / 100.0; powerFactor = val;
} }
u32 = getUnsignedNumber(AMS_OBIS_POWER_FACTOR_L1, sizeof(AMS_OBIS_POWER_FACTOR_L1), ((char *) (d))); val = getNumber(AMS_OBIS_POWER_FACTOR_L1, sizeof(AMS_OBIS_POWER_FACTOR_L1), ((char *) (d)));
if(u32 != 0xFFFFFFFF) { if(val != 0xFFFFFFFF) {
l1PowerFactor = u32 / 100.0; l1PowerFactor = val;
} }
u32 = getUnsignedNumber(AMS_OBIS_POWER_FACTOR_L2, sizeof(AMS_OBIS_POWER_FACTOR_L2), ((char *) (d))); val = getNumber(AMS_OBIS_POWER_FACTOR_L2, sizeof(AMS_OBIS_POWER_FACTOR_L2), ((char *) (d)));
if(u32 != 0xFFFFFFFF) { if(val != 0xFFFFFFFF) {
l2PowerFactor = u32 / 100.0; l2PowerFactor = val;
} }
u32 = getUnsignedNumber(AMS_OBIS_POWER_FACTOR_L3, sizeof(AMS_OBIS_POWER_FACTOR_L3), ((char *) (d))); val = getNumber(AMS_OBIS_POWER_FACTOR_L3, sizeof(AMS_OBIS_POWER_FACTOR_L3), ((char *) (d)));
if(u32 != 0xFFFFFFFF) { if(val != 0xFFFFFFFF) {
l3PowerFactor = u32 / 100.0; l3PowerFactor = val;
}
if(meterType == AmsTypeKamstrup) {
activeImportCounter *= 10;
activeExportCounter *= 10;
reactiveImportCounter *= 10;
reactiveExportCounter *= 10;
l1current /= 100;
l2current /= 100;
l3current /= 100;
powerFactor /= 100;
l1PowerFactor /= 100;
l2PowerFactor /= 100;
l3PowerFactor /= 100;
} }
lastUpdateMillis = millis(); lastUpdateMillis = millis();
@ -403,32 +393,35 @@ uint8_t IEC6205675::getString(uint8_t* obis, int matchlength, const char* ptr, c
return 0; return 0;
} }
uint32_t IEC6205675::getSignedNumber(uint8_t* obis, int matchlength, const char* ptr) { double IEC6205675::getNumber(uint8_t* obis, int matchlength, const char* ptr) {
CosemData* item = findObis(obis, matchlength, ptr); CosemData* item = findObis(obis, matchlength, ptr);
if(item != NULL) { return getNumber(item);
switch(item->base.type) {
case CosemTypeLongUnsigned:
return ntohs(item->lu.data);
case CosemTypeDLongUnsigned:
return ntohl(item->dlu.data);
case CosemTypeLongSigned:
return ntohs(item->lu.data);
}
}
return 0xFFFFFFFF;
} }
uint32_t IEC6205675::getUnsignedNumber(uint8_t* obis, int matchlength, const char* ptr) { double IEC6205675::getNumber(CosemData* item) {
CosemData* item = findObis(obis, matchlength, ptr); double val = 0xFFFFFFFF;
if(item != NULL) { if(item != NULL) {
char* pos = ((char*) item);
switch(item->base.type) { switch(item->base.type) {
case CosemTypeLongUnsigned: case CosemTypeLongUnsigned:
return ntohs(item->lu.data); val = ntohs(item->lu.data);
pos += 3;
break;
case CosemTypeDLongUnsigned: case CosemTypeDLongUnsigned:
return ntohl(item->dlu.data); val = ntohl(item->dlu.data);
pos += 5;
break;
case CosemTypeLongSigned:
val = ntohs(item->lu.data);
pos += 3;
break;
}
if(*pos++ == 0x02 && *pos++ == 0x02) {
int8_t scale = *++pos;
val *= pow(10, scale);
} }
} }
return 0xFFFFFFFF; return val;
} }
time_t IEC6205675::getTimestamp(uint8_t* obis, int matchlength, const char* ptr) { time_t IEC6205675::getTimestamp(uint8_t* obis, int matchlength, const char* ptr) {

View File

@ -17,8 +17,8 @@ private:
CosemData* getCosemDataAt(uint8_t index, const char* ptr); CosemData* getCosemDataAt(uint8_t index, const char* ptr);
CosemData* findObis(uint8_t* obis, int matchlength, const char* ptr); CosemData* findObis(uint8_t* obis, int matchlength, const char* ptr);
uint8_t getString(uint8_t* obis, int matchlength, const char* ptr, char* target); uint8_t getString(uint8_t* obis, int matchlength, const char* ptr, char* target);
uint32_t getSignedNumber(uint8_t* obis, int matchlength, const char* ptr); double getNumber(uint8_t* obis, int matchlength, const char* ptr);
uint32_t getUnsignedNumber(uint8_t* obis, int matchlength, const char* ptr); double getNumber(CosemData*);
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);