mirror of
https://github.com/UtilitechAS/amsreader-firmware.git
synced 2026-03-25 18:18:18 +00:00
Restructuring to be able to include precompiled kmp lib
This commit is contained in:
204
lib/MeterCommunicators/src/IEC6205621.cpp
Normal file
204
lib/MeterCommunicators/src/IEC6205621.cpp
Normal file
@@ -0,0 +1,204 @@
|
||||
/**
|
||||
* @copyright Utilitech AS 2023
|
||||
* License: Fair Source
|
||||
*
|
||||
*/
|
||||
|
||||
#include "IEC6205621.h"
|
||||
#include "Uptime.h"
|
||||
|
||||
IEC6205621::IEC6205621(const char* p, Timezone* tz, MeterConfig* meterConfig) {
|
||||
if(strlen(p) < 16)
|
||||
return;
|
||||
|
||||
String payload(p+1);
|
||||
|
||||
lastUpdateMillis = millis64();
|
||||
listId = payload.substring(payload.startsWith("/") ? 1 : 0, payload.indexOf("\n"));
|
||||
|
||||
if(listId.startsWith(F("ADN"))) {
|
||||
meterType = AmsTypeAidon;
|
||||
listId = listId.substring(0,4);
|
||||
} else if(listId.startsWith(F("KFM"))) {
|
||||
meterType = AmsTypeKaifa;
|
||||
listId = listId.substring(0,4);
|
||||
} else if(listId.startsWith(F("KMP"))) {
|
||||
meterType = AmsTypeKamstrup;
|
||||
listId = listId.substring(0,4);
|
||||
} else if(listId.startsWith(F("KAM"))) {
|
||||
meterType = AmsTypeKamstrup;
|
||||
listId = listId.substring(0,4);
|
||||
} else if(listId.startsWith(F("ISk"))) {
|
||||
meterType = AmsTypeIskra;
|
||||
listId = listId.substring(0,5);
|
||||
} else if(listId.startsWith(F("XMX"))) {
|
||||
meterType = AmsTypeLandisGyr;
|
||||
listId = listId.substring(0,6);
|
||||
} else if(listId.startsWith(F("Ene")) || listId.startsWith(F("EST"))) {
|
||||
meterType = AmsTypeSagemcom;
|
||||
listId = listId.substring(0,4);
|
||||
} else if(listId.startsWith(F("LGF"))) {
|
||||
meterType = AmsTypeLandisGyr;
|
||||
listId = listId.substring(0,4);
|
||||
} else {
|
||||
meterType = AmsTypeUnknown;
|
||||
listId = listId.substring(0,4);
|
||||
}
|
||||
|
||||
meterId = extract(payload, F("96.1.0"));
|
||||
if(meterId.isEmpty()) {
|
||||
meterId = extract(payload, F("0.0.5"));
|
||||
}
|
||||
|
||||
meterModel = extract(payload, F("96.1.1"));
|
||||
if(meterModel.isEmpty()) {
|
||||
meterModel = extract(payload, F("96.1.7"));
|
||||
if(meterModel.isEmpty()) {
|
||||
meterModel = payload.substring(payload.indexOf(listId) + listId.length(), payload.indexOf(F("\n")));
|
||||
meterModel.trim();
|
||||
}
|
||||
}
|
||||
|
||||
String timestamp = extract(payload, F("1.0.0"));
|
||||
if(timestamp.length() > 10) {
|
||||
tmElements_t tm;
|
||||
tm.Year = (timestamp.substring(0,2).toInt() + 2000) - 1970;
|
||||
tm.Month = timestamp.substring(4,6).toInt();
|
||||
tm.Day = timestamp.substring(2,4).toInt();
|
||||
tm.Hour = timestamp.substring(6,8).toInt();
|
||||
tm.Minute = timestamp.substring(8,10).toInt();
|
||||
tm.Second = timestamp.substring(10,12).toInt();
|
||||
meterTimestamp = makeTime(tm);
|
||||
if(tz != NULL) meterTimestamp = tz->toUTC(meterTimestamp);
|
||||
}
|
||||
|
||||
activeImportPower = (uint16_t) (extractDouble(payload, F("1.7.0")));
|
||||
activeExportPower = (uint16_t) (extractDouble(payload, F("2.7.0")));
|
||||
reactiveImportPower = (uint16_t) (extractDouble(payload, F("3.7.0")));
|
||||
reactiveExportPower = (uint16_t) (extractDouble(payload, F("4.7.0")));
|
||||
|
||||
if(activeImportPower > 0)
|
||||
listType = 1;
|
||||
|
||||
l1voltage = extractFloat(payload, F("32.7.0"));
|
||||
l2voltage = extractFloat(payload, F("52.7.0"));
|
||||
l3voltage = extractFloat(payload, F("72.7.0"));
|
||||
|
||||
l1current = extractFloat(payload, F("31.7.0"));
|
||||
l2current = extractFloat(payload, F("51.7.0"));
|
||||
l3current = extractFloat(payload, F("71.7.0"));
|
||||
|
||||
l1activeImportPower = extractFloat(payload, F("21.7.0"));
|
||||
l2activeImportPower = extractFloat(payload, F("41.7.0"));
|
||||
l3activeImportPower = extractFloat(payload, F("61.7.0"));
|
||||
|
||||
l1activeExportPower = extractFloat(payload, F("22.7.0"));
|
||||
l2activeExportPower = extractFloat(payload, F("42.7.0"));
|
||||
l3activeExportPower = extractFloat(payload, F("62.7.0"));
|
||||
|
||||
if(l1voltage > 0 || l2voltage > 0 || l3voltage > 0)
|
||||
listType = 2;
|
||||
|
||||
double val = 0.0;
|
||||
|
||||
val = extractDouble(payload, F("1.8.0"));
|
||||
if(val == 0) {
|
||||
for(int i = 1; i < 9; i++) {
|
||||
val += extractDouble(payload, "1.8." + String(i,10));
|
||||
}
|
||||
}
|
||||
if(val > 0) activeImportCounter = val / 1000;
|
||||
|
||||
val = extractDouble(payload, F("2.8.0"));
|
||||
if(val == 0) {
|
||||
for(int i = 1; i < 9; i++) {
|
||||
val += extractDouble(payload, "2.8." + String(i,10));
|
||||
}
|
||||
}
|
||||
if(val > 0) activeExportCounter = val / 1000;
|
||||
|
||||
val = extractDouble(payload, F("3.8.0"));
|
||||
if(val == 0) {
|
||||
for(int i = 1; i < 9; i++) {
|
||||
val += extractDouble(payload, "3.8." + String(i,10));
|
||||
}
|
||||
}
|
||||
if(val > 0) reactiveImportCounter = val / 1000;
|
||||
|
||||
val = extractDouble(payload, F("4.8.0"));
|
||||
if(val == 0) {
|
||||
for(int i = 1; i < 9; i++) {
|
||||
val += extractDouble(payload, "4.8." + String(i,10));
|
||||
}
|
||||
}
|
||||
if(val > 0) reactiveExportCounter = val / 1000;
|
||||
|
||||
if(activeImportCounter > 0 || activeExportCounter > 0 || reactiveImportCounter > 0 || reactiveExportCounter > 0)
|
||||
listType = 3;
|
||||
|
||||
if (l1activeImportPower > 0 || l2activeImportPower > 0 || l3activeImportPower > 0 || l1activeExportPower > 0 || l2activeExportPower > 0 || l3activeExportPower > 0)
|
||||
listType = 4;
|
||||
|
||||
if(meterConfig->wattageMultiplier > 0) {
|
||||
activeImportPower = activeImportPower > 0 ? activeImportPower * (meterConfig->wattageMultiplier / 1000.0) : 0;
|
||||
activeExportPower = activeExportPower > 0 ? activeExportPower * (meterConfig->wattageMultiplier / 1000.0) : 0;
|
||||
reactiveImportPower = reactiveImportPower > 0 ? reactiveImportPower * (meterConfig->wattageMultiplier / 1000.0) : 0;
|
||||
reactiveExportPower = reactiveExportPower > 0 ? reactiveExportPower * (meterConfig->wattageMultiplier / 1000.0) : 0;
|
||||
}
|
||||
if(meterConfig->voltageMultiplier > 0) {
|
||||
l1voltage = l1voltage > 0 ? l1voltage * (meterConfig->voltageMultiplier / 1000.0) : 0;
|
||||
l2voltage = l2voltage > 0 ? l2voltage * (meterConfig->voltageMultiplier / 1000.0) : 0;
|
||||
l3voltage = l3voltage > 0 ? l3voltage * (meterConfig->voltageMultiplier / 1000.0) : 0;
|
||||
}
|
||||
if(meterConfig->amperageMultiplier > 0) {
|
||||
l1current = l1current > 0 ? l1current * (meterConfig->amperageMultiplier / 1000.0) : 0;
|
||||
l2current = l2current > 0 ? l2current * (meterConfig->amperageMultiplier / 1000.0) : 0;
|
||||
l3current = l3current > 0 ? l3current * (meterConfig->amperageMultiplier / 1000.0) : 0;
|
||||
}
|
||||
if(meterConfig->accumulatedMultiplier > 0) {
|
||||
activeImportCounter = activeImportCounter > 0 ? activeImportCounter * (meterConfig->accumulatedMultiplier / 1000.0) : 0;
|
||||
activeExportCounter = activeExportCounter > 0 ? activeExportCounter * (meterConfig->accumulatedMultiplier / 1000.0) : 0;
|
||||
reactiveImportCounter = reactiveImportCounter > 0 ? reactiveImportCounter * (meterConfig->accumulatedMultiplier / 1000.0) : 0;
|
||||
reactiveExportCounter = reactiveExportCounter > 0 ? reactiveExportCounter * (meterConfig->accumulatedMultiplier / 1000.0) : 0;
|
||||
}
|
||||
|
||||
threePhase = l1voltage > 0 && l2voltage > 0 && l3voltage > 0;
|
||||
twoPhase = (l1voltage > 0 && l2voltage > 0) || (l2voltage > 0 && l3voltage > 0) || (l3voltage > 0 && l1voltage > 0);
|
||||
}
|
||||
|
||||
String IEC6205621::extract(String payload, String obis) {
|
||||
int a = payload.indexOf(String(":" + obis + "("));
|
||||
if(a > 0) {
|
||||
int b = payload.indexOf(F(")"), a);
|
||||
if(b > a) {
|
||||
return payload.substring(a+obis.length()+2, b);
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
double IEC6205621::extractDouble(String payload, String obis) {
|
||||
String str = extract(payload, obis);
|
||||
if(str.isEmpty()) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
int a = str.indexOf(F("*"));
|
||||
String val = str.substring(0,a);
|
||||
String unit = str.substring(a+1);
|
||||
|
||||
return unit.startsWith(F("k")) ? val.toDouble() * 1000 : val.toDouble();
|
||||
}
|
||||
|
||||
float IEC6205621::extractFloat(String payload, String obis) {
|
||||
String str = extract(payload, obis);
|
||||
if(str.isEmpty()) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
int a = str.indexOf(F("*"));
|
||||
String val = str.substring(0,a);
|
||||
String unit = str.substring(a+1);
|
||||
|
||||
return unit.startsWith(F("k")) ? val.toFloat() * 1000 : val.toFloat();
|
||||
}
|
||||
Reference in New Issue
Block a user