kopia lustrzana https://github.com/weetmuts/wmbusmeters
Refactor insert offset and key inside DVEntry add extractor methods to DVEntry.
rodzic
70a7078a57
commit
11763b2f22
|
@ -344,6 +344,11 @@ bool parseDV(Telegram *t,
|
|||
|
||||
(*dv_entries_ordered).push_back( &(*dv_entries)[key].second );
|
||||
|
||||
DVEntry *dve = (*dv_entries_ordered).back();
|
||||
DVEntry *dvee = &(*dv_entries)[key].second;
|
||||
|
||||
assert(key == dve->dif_vif_key.str() && key == dvee->dif_vif_key.str());
|
||||
|
||||
if (value.length() > 0) {
|
||||
// This call increments data with datalen.
|
||||
t->addExplanationAndIncrementPos(data, datalen, KindOfData::CONTENT, Understanding::NONE, "%s", value.c_str());
|
||||
|
@ -413,7 +418,6 @@ bool findKeyWithNr(MeasurementType mit, VIFRange vif_range, StorageNr storagenr,
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
void extractDV(DifVifKey &dvk, uchar *dif, uchar *vif)
|
||||
{
|
||||
string tmp = dvk.str();
|
||||
|
@ -832,21 +836,26 @@ bool extractDVHexString(map<string,pair<int,DVEntry>> *dv_entries,
|
|||
bool extractDVReadableString(map<string,pair<int,DVEntry>> *dv_entries,
|
||||
string key,
|
||||
int *offset,
|
||||
string *value)
|
||||
string *out)
|
||||
{
|
||||
if ((*dv_entries).count(key) == 0) {
|
||||
verbose("(dvparser) warning: cannot extract string from non-existant key \"%s\"\n", key.c_str());
|
||||
*offset = -1;
|
||||
return false;
|
||||
}
|
||||
uchar dif, vif;
|
||||
extractDV(key, &dif, &vif);
|
||||
int t = dif&0xf;
|
||||
|
||||
pair<int,DVEntry>& p = (*dv_entries)[key];
|
||||
*offset = p.first;
|
||||
|
||||
string v = p.second.value;
|
||||
return p.second.extractReadableString(out);
|
||||
}
|
||||
|
||||
bool DVEntry::extractReadableString(string *out)
|
||||
{
|
||||
uchar dif, vif;
|
||||
extractDV(dif_vif_key, &dif, &vif);
|
||||
int t = dif&0xf;
|
||||
|
||||
string v = value;
|
||||
|
||||
if (t == 0x1 || // 8 Bit Integer/Binary
|
||||
t == 0x2 || // 16 Bit Integer/Binary
|
||||
|
@ -872,7 +881,7 @@ bool extractDVReadableString(map<string,pair<int,DVEntry>> *dv_entries,
|
|||
v = reverseBCD(v);
|
||||
}
|
||||
|
||||
*value = v;
|
||||
*out = v;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -913,48 +922,54 @@ bool extractTime(uchar hi, uchar lo, struct tm *date)
|
|||
bool extractDVdate(map<string,pair<int,DVEntry>> *dv_entries,
|
||||
string key,
|
||||
int *offset,
|
||||
struct tm *value)
|
||||
struct tm *out)
|
||||
{
|
||||
if ((*dv_entries).count(key) == 0)
|
||||
{
|
||||
verbose("(dvparser) warning: cannot extract date from non-existant key \"%s\"\n", key.c_str());
|
||||
*offset = -1;
|
||||
memset(value, 0, sizeof(struct tm));
|
||||
memset(out, 0, sizeof(struct tm));
|
||||
return false;
|
||||
}
|
||||
pair<int,DVEntry>& p = (*dv_entries)[key];
|
||||
*offset = p.first;
|
||||
|
||||
return p.second.extractDate(out);
|
||||
}
|
||||
|
||||
bool DVEntry::extractDate(struct tm *out)
|
||||
{
|
||||
// This will install the correct timezone
|
||||
// offset tm_gmtoff into the timestamp.
|
||||
time_t t = time(NULL);
|
||||
localtime_r(&t, value);
|
||||
value->tm_hour = 0;
|
||||
value->tm_min = 0;
|
||||
value->tm_sec = 0;
|
||||
value->tm_mday = 0;
|
||||
value->tm_mon = 0;
|
||||
value->tm_year = 0;
|
||||
localtime_r(&t, out);
|
||||
out->tm_hour = 0;
|
||||
out->tm_min = 0;
|
||||
out->tm_sec = 0;
|
||||
out->tm_mday = 0;
|
||||
out->tm_mon = 0;
|
||||
out->tm_year = 0;
|
||||
|
||||
uchar dif, vif;
|
||||
extractDV(key, &dif, &vif);
|
||||
extractDV(dif_vif_key, &dif, &vif);
|
||||
|
||||
pair<int,DVEntry>& p = (*dv_entries)[key];
|
||||
*offset = p.first;
|
||||
vector<uchar> v;
|
||||
hex2bin(p.second.value, &v);
|
||||
hex2bin(value, &v);
|
||||
|
||||
bool ok = true;
|
||||
if (v.size() == 2) {
|
||||
ok &= extractDate(v[1], v[0], value);
|
||||
ok &= ::extractDate(v[1], v[0], out);
|
||||
}
|
||||
else if (v.size() == 4) {
|
||||
ok &= extractDate(v[3], v[2], value);
|
||||
ok &= extractTime(v[1], v[0], value);
|
||||
ok &= ::extractDate(v[3], v[2], out);
|
||||
ok &= ::extractTime(v[1], v[0], out);
|
||||
}
|
||||
else if (v.size() == 6) {
|
||||
ok &= extractDate(v[4], v[3], value);
|
||||
ok &= extractTime(v[2], v[1], value);
|
||||
ok &= ::extractDate(v[4], v[3], out);
|
||||
ok &= ::extractTime(v[2], v[1], out);
|
||||
// ..ss ssss
|
||||
int sec = (0x3f) & v[0];
|
||||
value->tm_sec = sec;
|
||||
out->tm_sec = sec;
|
||||
// some daylight saving time decoding needed here....
|
||||
}
|
||||
|
||||
|
|
|
@ -147,20 +147,23 @@ static IndexNr AnyIndexNr = IndexNr(-1);
|
|||
|
||||
struct DVEntry
|
||||
{
|
||||
int offset { 0 }; // Where in the telegram this dventry was found.
|
||||
DifVifKey dif_vif_key { "" };
|
||||
MeasurementType measurement_type {};
|
||||
Vif vif { 0 };
|
||||
StorageNr storage_nr { 0 };
|
||||
TariffNr tariff_nr { 0 };
|
||||
SubUnitNr subunit_nr { 0 };
|
||||
int offset; // Where in the telegram this dventry was found.
|
||||
DifVifKey dif_vif_key;
|
||||
MeasurementType measurement_type;
|
||||
Vif vif;
|
||||
StorageNr storage_nr;
|
||||
TariffNr tariff_nr;
|
||||
SubUnitNr subunit_nr;
|
||||
std::string value;
|
||||
DVEntry() {}
|
||||
DVEntry(int off, DifVifKey dvk, MeasurementType mt, Vif vi, StorageNr st, TariffNr ta, SubUnitNr su, std::string &val) :
|
||||
offset(off), dif_vif_key(dvk), measurement_type(mt), vif(vi), storage_nr(st), tariff_nr(ta), subunit_nr(su), value(val) {}
|
||||
DVEntry() :
|
||||
offset(999999), dif_vif_key("????"), measurement_type(MeasurementType::Instantaneous), vif(0), storage_nr(0), tariff_nr(0), subunit_nr(0), value("x") {}
|
||||
|
||||
bool extractDouble(double *out, bool auto_scale, bool assume_signed);
|
||||
bool extractLong(uint64_t *out);
|
||||
bool extractDate(struct tm *out);
|
||||
bool extractReadableString(std::string *out);
|
||||
};
|
||||
|
||||
struct FieldMatcher
|
||||
|
|
|
@ -2076,28 +2076,31 @@ bool FieldInfo::extractNumeric(Meter *m, Telegram *t, DVEntry *dve)
|
|||
bool found = false;
|
||||
string key = difVifKey().str();
|
||||
|
||||
int offset {};
|
||||
if (key == "")
|
||||
if (dve == NULL)
|
||||
{
|
||||
// Search for key.
|
||||
bool ok = findKeyWithNr(measurementType(),
|
||||
vifRange(),
|
||||
storageNr().intValue(),
|
||||
tariffNr().intValue(),
|
||||
indexNr().intValue(),
|
||||
&key,
|
||||
&t->dv_entries);
|
||||
if (!ok) return false;
|
||||
if (key == "")
|
||||
{
|
||||
// Search for key.
|
||||
bool ok = findKeyWithNr(measurementType(),
|
||||
vifRange(),
|
||||
storageNr().intValue(),
|
||||
tariffNr().intValue(),
|
||||
indexNr().intValue(),
|
||||
&key,
|
||||
&t->dv_entries);
|
||||
// No entry was found.
|
||||
if (!ok) return false;
|
||||
}
|
||||
// No entry with this key was found.
|
||||
if (t->dv_entries.count(key) == 0) return false;
|
||||
dve = &t->dv_entries[key].second;
|
||||
}
|
||||
double extracted_double_value = NAN;
|
||||
if (extractDVdouble(&t->dv_entries,
|
||||
key,
|
||||
&offset,
|
||||
&extracted_double_value,
|
||||
vifScaling() == VifScaling::Auto ||
|
||||
vifScaling() == VifScaling::AutoSigned,
|
||||
vifScaling() == VifScaling::NoneSigned ||
|
||||
vifScaling() == VifScaling::AutoSigned))
|
||||
if (dve->extractDouble(&extracted_double_value,
|
||||
vifScaling() == VifScaling::Auto ||
|
||||
vifScaling() == VifScaling::AutoSigned,
|
||||
vifScaling() == VifScaling::NoneSigned ||
|
||||
vifScaling() == VifScaling::AutoSigned))
|
||||
{
|
||||
Unit decoded_unit = defaultUnit();
|
||||
if (vifRange() != VIFRange::Any &&
|
||||
|
@ -2109,7 +2112,7 @@ bool FieldInfo::extractNumeric(Meter *m, Telegram *t, DVEntry *dve)
|
|||
decoded_unit = toDefaultUnit(vifRange());
|
||||
}
|
||||
setValueDouble(decoded_unit, extracted_double_value);
|
||||
t->addMoreExplanation(offset, renderJson(&m->conversions()));
|
||||
t->addMoreExplanation(dve->offset, renderJson(&m->conversions()));
|
||||
found = true;
|
||||
}
|
||||
return found;
|
||||
|
@ -2119,55 +2122,65 @@ bool FieldInfo::extractString(Meter *m, Telegram *t, DVEntry *dve)
|
|||
{
|
||||
bool found = false;
|
||||
string key = difVifKey().str();
|
||||
int offset {};
|
||||
if (key == "")
|
||||
|
||||
if (dve == NULL)
|
||||
{
|
||||
// Search for key.
|
||||
bool ok = findKeyWithNr(measurementType(),
|
||||
vifRange(),
|
||||
storageNr().intValue(),
|
||||
tariffNr().intValue(),
|
||||
indexNr().intValue(),
|
||||
&key,
|
||||
&t->dv_entries);
|
||||
if (!ok) return false;
|
||||
if (key == "")
|
||||
{
|
||||
// Search for key.
|
||||
bool ok = findKeyWithNr(measurementType(),
|
||||
vifRange(),
|
||||
storageNr().intValue(),
|
||||
tariffNr().intValue(),
|
||||
indexNr().intValue(),
|
||||
&key,
|
||||
&t->dv_entries);
|
||||
// No entry was found.
|
||||
if (!ok) return false;
|
||||
}
|
||||
// No entry with this key was found.
|
||||
if (t->dv_entries.count(key) == 0) return false;
|
||||
dve = &t->dv_entries[key].second;
|
||||
}
|
||||
assert(dve != NULL);
|
||||
assert(dve->dif_vif_key.str() == key);
|
||||
|
||||
uint64_t extracted_bits {};
|
||||
if (lookup_.hasLookups())
|
||||
{
|
||||
if (extractDVlong(&t->dv_entries, key, &offset, &extracted_bits))
|
||||
if (dve->extractLong(&extracted_bits))
|
||||
{
|
||||
string translated_bits = lookup().translate(extracted_bits);
|
||||
setValueString(translated_bits);
|
||||
t->addMoreExplanation(offset, renderJsonText());
|
||||
t->addMoreExplanation(dve->offset, renderJsonText());
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
else if (vifRange() == VIFRange::DateTime)
|
||||
{
|
||||
struct tm datetime;
|
||||
extractDVdate(&t->dv_entries, key, &offset, &datetime);
|
||||
dve->extractDate(&datetime);
|
||||
string extracted_device_date_time = strdatetime(&datetime);
|
||||
setValueString(extracted_device_date_time);
|
||||
t->addMoreExplanation(offset, renderJsonText());
|
||||
t->addMoreExplanation(dve->offset, renderJsonText());
|
||||
found = true;
|
||||
}
|
||||
else if (vifRange() == VIFRange::Date)
|
||||
{
|
||||
struct tm date;
|
||||
extractDVdate(&t->dv_entries, key, &offset, &date);
|
||||
dve->extractDate(&date);
|
||||
string extracted_device_date = strdate(&date);
|
||||
setValueString(extracted_device_date);
|
||||
t->addMoreExplanation(offset, renderJsonText());
|
||||
t->addMoreExplanation(dve->offset, renderJsonText());
|
||||
found = true;
|
||||
}
|
||||
else if (vifRange() == VIFRange::EnhancedIdentification ||
|
||||
vifRange() == VIFRange::FabricationNo)
|
||||
{
|
||||
string extracted_id;
|
||||
extractDVReadableString(&t->dv_entries, key, &offset, &extracted_id);
|
||||
dve->extractReadableString(&extracted_id);
|
||||
setValueString(extracted_id);
|
||||
t->addMoreExplanation(offset, renderJsonText());
|
||||
t->addMoreExplanation(dve->offset, renderJsonText());
|
||||
found = true;
|
||||
}
|
||||
else
|
||||
|
|
Ładowanie…
Reference in New Issue