kopia lustrzana https://github.com/weetmuts/wmbusmeters
Refactor aventieswm driver.
rodzic
75a18afd11
commit
8168e66d6a
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (C) 2020 Fredrik Öhrström
|
||||
Copyright (C) 2020-2021 Fredrik Öhrström
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -24,196 +24,105 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
struct MeterAventiesWM : public virtual MeterCommonImplementation {
|
||||
MeterAventiesWM(MeterInfo &mi);
|
||||
|
||||
// Total water counted through the meter
|
||||
double totalWaterConsumption(Unit u);
|
||||
bool hasTotalWaterConsumption();
|
||||
|
||||
double consumptionAtSetDate(Unit u);
|
||||
struct MeterAventiesWM : public virtual MeterCommonImplementation
|
||||
{
|
||||
MeterAventiesWM(MeterInfo &mi, DriverInfo &di);
|
||||
|
||||
private:
|
||||
void processContent(Telegram *t);
|
||||
|
||||
string errorFlagsHumanReadable();
|
||||
|
||||
double total_water_consumption_m3_ {};
|
||||
double consumption_at_set_date_m3_[14];
|
||||
uint16_t error_flags_;
|
||||
|
||||
string error_flags_;
|
||||
};
|
||||
|
||||
shared_ptr<Meter> createAventiesWM(MeterInfo &mi)
|
||||
static bool ok = registerDriver([](DriverInfo&di)
|
||||
{
|
||||
return shared_ptr<Meter>(new MeterAventiesWM(mi));
|
||||
}
|
||||
di.setName("aventieswm");
|
||||
di.setMeterType(MeterType::WaterMeter);
|
||||
di.setExpectedTPLSecurityMode(TPLSecurityMode::AES_CBC_IV);
|
||||
di.addLinkMode(LinkMode::T1);
|
||||
di.addDetection(MANUFACTURER_AAA, 0x07, 0x25);
|
||||
di.setConstructor([](MeterInfo& mi, DriverInfo& di){ return shared_ptr<Meter>(new MeterAventiesWM(mi, di)); });
|
||||
});
|
||||
|
||||
MeterAventiesWM::MeterAventiesWM(MeterInfo &mi) :
|
||||
MeterCommonImplementation(mi, "aventieswm")
|
||||
MeterAventiesWM::MeterAventiesWM(MeterInfo &mi, DriverInfo &di) :
|
||||
MeterCommonImplementation(mi, di)
|
||||
{
|
||||
setMeterType(MeterType::WaterMeter);
|
||||
|
||||
setExpectedTPLSecurityMode(TPLSecurityMode::AES_CBC_IV);
|
||||
|
||||
addLinkMode(LinkMode::T1);
|
||||
|
||||
addPrint("total", Quantity::Volume,
|
||||
[&](Unit u){ return totalWaterConsumption(u); },
|
||||
"The total water consumption recorded by this meter.",
|
||||
true, true);
|
||||
|
||||
/* addPrint("set_date", Quantity::Text,
|
||||
[&](){ return setDate(); },
|
||||
"The most recent billing period date.",
|
||||
false, true);
|
||||
*/
|
||||
addFieldWithExtractor(
|
||||
"total",
|
||||
Quantity::Volume,
|
||||
NoDifVifKey,
|
||||
VifScaling::Auto,
|
||||
MeasurementType::Instantaneous,
|
||||
ValueInformation::Volume,
|
||||
StorageNr(0),
|
||||
TariffNr(0),
|
||||
IndexNr(1),
|
||||
PrintProperty::JSON | PrintProperty::FIELD | PrintProperty::IMPORTANT,
|
||||
"The total water consumption recorded by this meter.",
|
||||
SET_FUNC(total_water_consumption_m3_, Unit::M3),
|
||||
GET_FUNC(total_water_consumption_m3_, Unit::M3));
|
||||
|
||||
for (int i=1; i<=14; ++i)
|
||||
{
|
||||
string msg, info;
|
||||
strprintf(msg, "consumption_at_set_date_%d", i);
|
||||
strprintf(info, "Water consumption at the %d billing period date.", i);
|
||||
addPrint(msg, Quantity::Volume,
|
||||
[this,i](Unit u){ return consumption_at_set_date_m3_[i-1]; },
|
||||
info,
|
||||
false, true);
|
||||
addFieldWithExtractor(
|
||||
msg,
|
||||
Quantity::Volume,
|
||||
NoDifVifKey,
|
||||
VifScaling::Auto,
|
||||
MeasurementType::Instantaneous,
|
||||
ValueInformation::Volume,
|
||||
StorageNr(i),
|
||||
TariffNr(0),
|
||||
IndexNr(1),
|
||||
PrintProperty::JSON,
|
||||
info,
|
||||
SET_FUNC(consumption_at_set_date_m3_[i-1], Unit::M3),
|
||||
GET_FUNC(consumption_at_set_date_m3_[i-1], Unit::M3));
|
||||
}
|
||||
|
||||
addPrint("error_flags", Quantity::Text,
|
||||
[&](){ return errorFlagsHumanReadable(); },
|
||||
"Error flags.",
|
||||
true, true);
|
||||
addStringFieldWithExtractorAndLookup(
|
||||
"error_flags",
|
||||
Quantity::Text,
|
||||
DifVifKey("02FD17"),
|
||||
MeasurementType::Unknown,
|
||||
ValueInformation::Any,
|
||||
AnyStorageNr,
|
||||
AnyTariffNr,
|
||||
IndexNr(1),
|
||||
PrintProperty::JSON | PrintProperty::FIELD,
|
||||
"Error flags.",
|
||||
SET_STRING_FUNC(error_flags_),
|
||||
GET_STRING_FUNC(error_flags_),
|
||||
{
|
||||
{
|
||||
{
|
||||
"ERROR_FLAGS",
|
||||
Translate::Type::BitToString,
|
||||
0xffff,
|
||||
{
|
||||
{ 0x01, "MEASUREMENT" },
|
||||
{ 0x02, "SABOTAGE" },
|
||||
{ 0x04, "BATTERY" },
|
||||
{ 0x08, "CS" },
|
||||
{ 0x10, "HF" },
|
||||
{ 0x20, "RESET" }
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
string MeterAventiesWM::errorFlagsHumanReadable()
|
||||
{
|
||||
string s;
|
||||
if (error_flags_ & 0x01) s += "MEASUREMENT ";
|
||||
if (error_flags_ & 0x02) s += "SABOTAGE ";
|
||||
if (error_flags_ & 0x04) s += "BATTERY ";
|
||||
if (error_flags_ & 0x08) s += "CS ";
|
||||
if (error_flags_ & 0x10) s += "HF ";
|
||||
if (error_flags_ & 0x20) s += "RESET ";
|
||||
|
||||
if (s.length() > 0) {
|
||||
s.pop_back();
|
||||
return s;
|
||||
}
|
||||
|
||||
if (error_flags_ != 0 && s.length() == 0) {
|
||||
// Some higher bits are set that we do not know about! Fall back to printing the number!
|
||||
strprintf(s, "0x%04X", error_flags_);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
// Test: Votten aventieswm 61070071 A004EB23329A477F1DD2D7820B56EB3D
|
||||
// telegram=76442104710007612507727100076121042507B5006005E2E95A3C2A1279A5415E6732679B43369FD5FDDDD783EEEBB48236D34E7C94AF0A18A5FDA5F7D64111EB42D4D891622139F2952F9D12A20088DFA4CF8123871123EE1F6C1DCEA414879DDB4E05E508F1826D7EFBA6964DF804C9261EA23BBF03
|
||||
// {"media":"water","meter":"aventieswm","name":"Votten","id":"61070071","total_m3":466.472,"consumption_at_set_date_1_m3":465.96,"consumption_at_set_date_2_m3":458.88,"consumption_at_set_date_3_m3":449.65,"consumption_at_set_date_4_m3":442.35,"consumption_at_set_date_5_m3":431.07,"consumption_at_set_date_6_m3":423.98,"consumption_at_set_date_7_m3":415.23,"consumption_at_set_date_8_m3":409.03,"consumption_at_set_date_9_m3":400.79,"consumption_at_set_date_10_m3":393.2,"consumption_at_set_date_11_m3":388.63,"consumption_at_set_date_12_m3":379.26,"consumption_at_set_date_13_m3":371.26,"consumption_at_set_date_14_m3":357.84,"error_flags":"","timestamp":"1111-11-11T11:11:11Z"}
|
||||
// |Votten;61070071;466.472000;;1111-11-11 11:11.11
|
||||
|
||||
|
||||
void MeterAventiesWM::processContent(Telegram *t)
|
||||
{
|
||||
/*
|
||||
(q400) 17: 2f2f decrypt check bytes
|
||||
(q400) 19: 04 dif (32 Bit Integer/Binary Instantaneous value)
|
||||
(q400) 1a: 13 vif (Volume l)
|
||||
(q400) 1b: * 1F480000 total consumption (18.463000 m3)
|
||||
(q400) 1f: 43 dif (24 Bit Integer/Binary Instantaneous value storagenr=1)
|
||||
(q400) 20: 14 vif (Volume 10⁻² m³)
|
||||
(q400) 21: * 360700 consumption at set date (18.460000 m3)
|
||||
(q400) 24: 83 dif (24 Bit Integer/Binary Instantaneous value)
|
||||
(q400) 25: 01 dife (subunit=0 tariff=0 storagenr=2)
|
||||
(q400) 26: 14 vif (Volume 10⁻² m³)
|
||||
(q400) 27: FE0600
|
||||
(q400) 2a: C3 dif (24 Bit Integer/Binary Instantaneous value storagenr=1)
|
||||
(q400) 2b: 01 dife (subunit=0 tariff=0 storagenr=3)
|
||||
(q400) 2c: 14 vif (Volume 10⁻² m³)
|
||||
(q400) 2d: DD0600
|
||||
(q400) 30: 83 dif (24 Bit Integer/Binary Instantaneous value)
|
||||
(q400) 31: 02 dife (subunit=0 tariff=0 storagenr=4)
|
||||
(q400) 32: 14 vif (Volume 10⁻² m³)
|
||||
(q400) 33: C30600
|
||||
(q400) 36: C3 dif (24 Bit Integer/Binary Instantaneous value storagenr=1)
|
||||
(q400) 37: 02 dife (subunit=0 tariff=0 storagenr=5)
|
||||
(q400) 38: 14 vif (Volume 10⁻² m³)
|
||||
(q400) 39: BD0600
|
||||
(q400) 3c: 83 dif (24 Bit Integer/Binary Instantaneous value)
|
||||
(q400) 3d: 03 dife (subunit=0 tariff=0 storagenr=6)
|
||||
(q400) 3e: 14 vif (Volume 10⁻² m³)
|
||||
(q400) 3f: BC0600
|
||||
(q400) 42: C3 dif (24 Bit Integer/Binary Instantaneous value storagenr=1)
|
||||
(q400) 43: 03 dife (subunit=0 tariff=0 storagenr=7)
|
||||
(q400) 44: 14 vif (Volume 10⁻² m³)
|
||||
(q400) 45: 000000
|
||||
(q400) 48: 83 dif (24 Bit Integer/Binary Instantaneous value)
|
||||
(q400) 49: 04 dife (subunit=0 tariff=0 storagenr=8)
|
||||
(q400) 4a: 14 vif (Volume 10⁻² m³)
|
||||
(q400) 4b: BB0600
|
||||
(q400) 4e: C3 dif (24 Bit Integer/Binary Instantaneous value storagenr=1)
|
||||
(q400) 4f: 04 dife (subunit=0 tariff=0 storagenr=9)
|
||||
(q400) 50: 14 vif (Volume 10⁻² m³)
|
||||
(q400) 51: BB0600
|
||||
(q400) 54: 83 dif (24 Bit Integer/Binary Instantaneous value)
|
||||
(q400) 55: 05 dife (subunit=0 tariff=0 storagenr=10)
|
||||
(q400) 56: 14 vif (Volume 10⁻² m³)
|
||||
(q400) 57: BA0600
|
||||
(q400) 5a: C3 dif (24 Bit Integer/Binary Instantaneous value storagenr=1)
|
||||
(q400) 5b: 05 dife (subunit=0 tariff=0 storagenr=11)
|
||||
(q400) 5c: 14 vif (Volume 10⁻² m³)
|
||||
(q400) 5d: B80600
|
||||
(q400) 60: 83 dif (24 Bit Integer/Binary Instantaneous value)
|
||||
(q400) 61: 06 dife (subunit=0 tariff=0 storagenr=12)
|
||||
(q400) 62: 14 vif (Volume 10⁻² m³)
|
||||
(q400) 63: 220600
|
||||
(q400) 66: C3 dif (24 Bit Integer/Binary Instantaneous value storagenr=1)
|
||||
(q400) 67: 06 dife (subunit=0 tariff=0 storagenr=13)
|
||||
(q400) 68: 14 vif (Volume 10⁻² m³)
|
||||
(q400) 69: DC0500
|
||||
(q400) 6c: 83 dif (24 Bit Integer/Binary Instantaneous value)
|
||||
(q400) 6d: 07 dife (subunit=0 tariff=0 storagenr=14)
|
||||
(q400) 6e: 14 vif (Volume 10⁻² m³)
|
||||
(q400) 6f: CD0500
|
||||
(q400) 72: 02 dif (16 Bit Integer/Binary Instantaneous value)
|
||||
(q400) 73: FD vif (Second extension FD of VIF-codes)
|
||||
(q400) 74: 17 vife (Error flags (binary))
|
||||
(q400) 75: 0000 */
|
||||
int offset;
|
||||
string key;
|
||||
|
||||
if(findKey(MeasurementType::Unknown, ValueInformation::Volume, 0, 0, &key, &t->values)) {
|
||||
extractDVdouble(&t->values, key, &offset, &total_water_consumption_m3_);
|
||||
t->addMoreExplanation(offset, " total consumption (%f m3)", total_water_consumption_m3_);
|
||||
}
|
||||
|
||||
for (int i=1; i<=14; ++i)
|
||||
{
|
||||
if (findKey(MeasurementType::Unknown, ValueInformation::Volume, i, 0, &key, &t->values))
|
||||
{
|
||||
string info;
|
||||
strprintf(info, " consumption at set date %d (%%f m3)", i);
|
||||
extractDVdouble(&t->values, key, &offset, &consumption_at_set_date_m3_[i-1]);
|
||||
t->addMoreExplanation(offset, info.c_str(), consumption_at_set_date_m3_[i-1]);
|
||||
}
|
||||
}
|
||||
|
||||
key = "02FD17";
|
||||
if (hasKey(&t->values, key)) {
|
||||
extractDVuint16(&t->values, "02FD17", &offset, &error_flags_);
|
||||
t->addMoreExplanation(offset, " error flags (%04X)", error_flags_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
double MeterAventiesWM::totalWaterConsumption(Unit u)
|
||||
{
|
||||
assertQuantity(u, Quantity::Volume);
|
||||
return convert(total_water_consumption_m3_, Unit::M3, u);
|
||||
}
|
||||
|
||||
bool MeterAventiesWM::hasTotalWaterConsumption()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
double MeterAventiesWM::consumptionAtSetDate(Unit u)
|
||||
{
|
||||
return consumption_at_set_date_m3_[0];
|
||||
}
|
||||
// Test: Votten aventieswm 61070071 NOKEY
|
||||
// telegram=76442104710007612507727100076121042507B50060052F2F0413281E0700431404B60083011440B300C30114A5AF00830214CBAC00C3021463A8008303149EA500C3031433A200830414C79F00C304148F9C00830514989900C30514CF9700830614269400C30614069100830714C88B0002FD171111
|
||||
// {"media":"water","meter":"aventieswm","name":"Votten","id":"61070071","total_m3":466.472,"consumption_at_set_date_1_m3":465.96,"consumption_at_set_date_2_m3":458.88,"consumption_at_set_date_3_m3":449.65,"consumption_at_set_date_4_m3":442.35,"consumption_at_set_date_5_m3":431.07,"consumption_at_set_date_6_m3":423.98,"consumption_at_set_date_7_m3":415.23,"consumption_at_set_date_8_m3":409.03,"consumption_at_set_date_9_m3":400.79,"consumption_at_set_date_10_m3":393.2,"consumption_at_set_date_11_m3":388.63,"consumption_at_set_date_12_m3":379.26,"consumption_at_set_date_13_m3":371.26,"consumption_at_set_date_14_m3":357.84,"error_flags":"MEASUREMENT HF UNKNOWN_ERROR_FLAGS(0x1100)","timestamp":"1111-11-11T11:11:11Z"}
|
||||
// |Votten;61070071;466.472000;MEASUREMENT HF UNKNOWN_ERROR_FLAGS(0x1100);1111-11-11 11:11.11
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
// meter driver, manufacturer, media, version
|
||||
//
|
||||
#define METER_DETECTION \
|
||||
X(AVENTIESWM,MANUFACTURER_AAA, 0x07, 0x25) \
|
||||
X(AVENTIESHCA,MANUFACTURER_AAA, 0x08, 0x55) \
|
||||
X(APATOR08, 0x8614/*APT?*/, 0x03, 0x03) \
|
||||
X(APATOR162, MANUFACTURER_APA, 0x06, 0x05) \
|
||||
|
|
|
@ -602,7 +602,8 @@ void MeterCommonImplementation::addPrint(string vname, Quantity vquantity,
|
|||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
NULL,
|
||||
NoLookup
|
||||
));
|
||||
}
|
||||
|
||||
|
@ -633,7 +634,8 @@ void MeterCommonImplementation::addPrint(string vname, Quantity vquantity, Unit
|
|||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
NULL,
|
||||
NoLookup
|
||||
));
|
||||
}
|
||||
|
||||
|
@ -662,7 +664,8 @@ void MeterCommonImplementation::addPrint(string vname, Quantity vquantity,
|
|||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
NULL,
|
||||
NoLookup
|
||||
));
|
||||
}
|
||||
|
||||
|
@ -739,7 +742,8 @@ void MeterCommonImplementation::addFieldWithExtractor(
|
|||
setValueFunc,
|
||||
NULL,
|
||||
extract,
|
||||
NULL
|
||||
NULL,
|
||||
NoLookup
|
||||
));
|
||||
}
|
||||
|
||||
|
@ -817,7 +821,87 @@ void MeterCommonImplementation::addStringFieldWithExtractor(
|
|||
NULL,
|
||||
setValueFunc,
|
||||
NULL,
|
||||
extract
|
||||
extract,
|
||||
NoLookup
|
||||
));
|
||||
}
|
||||
|
||||
void MeterCommonImplementation::addStringFieldWithExtractorAndLookup(
|
||||
string vname,
|
||||
Quantity vquantity,
|
||||
DifVifKey dif_vif_key,
|
||||
MeasurementType mt,
|
||||
ValueInformation vi,
|
||||
StorageNr s,
|
||||
TariffNr t,
|
||||
IndexNr i,
|
||||
int print_properties,
|
||||
string help,
|
||||
function<void(string)> setValueFunc,
|
||||
function<string()> getValueFunc,
|
||||
Translate::Lookup lookup)
|
||||
{
|
||||
string default_unit = unitToStringLowerCase(defaultUnitForQuantity(vquantity));
|
||||
string field_name = vname+"_"+default_unit;
|
||||
fields_.push_back(field_name);
|
||||
|
||||
// Compose the extract function.
|
||||
function<bool(FieldInfo *p,Meter *m, Telegram *t)> extract =
|
||||
[](FieldInfo *fi, Meter *m, Telegram *t)
|
||||
{
|
||||
bool found = false;
|
||||
string key = fi->difVifKey().str();
|
||||
int offset {};
|
||||
if (key == "")
|
||||
{
|
||||
// Search for key.
|
||||
bool ok = findKeyWithNr(fi->measurementType(),
|
||||
fi->valueInformation(),
|
||||
fi->storageNr().intValue(),
|
||||
fi->tariffNr().intValue(),
|
||||
fi->indexNr().intValue(),
|
||||
&key,
|
||||
&t->values);
|
||||
if (!ok) return false;
|
||||
}
|
||||
uint64_t extracted_bits {};
|
||||
if (extractDVlong(&t->values, key, &offset, &extracted_bits))
|
||||
{
|
||||
string translated_bits = fi->lookup().translate(extracted_bits);
|
||||
fi->setValueString(translated_bits);
|
||||
t->addMoreExplanation(offset, fi->renderJsonText());
|
||||
found = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
return found;
|
||||
};
|
||||
|
||||
prints_.push_back(
|
||||
FieldInfo(vname,
|
||||
vquantity,
|
||||
defaultUnitForQuantity(vquantity),
|
||||
dif_vif_key,
|
||||
VifScaling::None,
|
||||
mt,
|
||||
vi,
|
||||
s,
|
||||
t,
|
||||
i,
|
||||
help,
|
||||
(print_properties & PrintProperty::FIELD) != 0,
|
||||
(print_properties & PrintProperty::JSON) != 0,
|
||||
(print_properties & PrintProperty::IMPORTANT) != 0,
|
||||
field_name,
|
||||
NULL,
|
||||
getValueFunc,
|
||||
NULL,
|
||||
setValueFunc,
|
||||
NULL,
|
||||
extract,
|
||||
lookup
|
||||
));
|
||||
}
|
||||
|
||||
|
|
11
src/meters.h
11
src/meters.h
|
@ -21,6 +21,7 @@
|
|||
#include"dvparser.h"
|
||||
#include"util.h"
|
||||
#include"units.h"
|
||||
#include"translatebits.h"
|
||||
#include"wmbus.h"
|
||||
|
||||
#include<functional>
|
||||
|
@ -52,7 +53,6 @@ LIST_OF_METER_TYPES
|
|||
X(unknown, 0, UnknownMeter, UNKNOWN, Unknown) \
|
||||
X(apator08, T1_bit, WaterMeter, APATOR08, Apator08) \
|
||||
X(apator162, C1_bit|T1_bit, WaterMeter, APATOR162, Apator162) \
|
||||
X(aventieswm, T1_bit, WaterMeter, AVENTIESWM, AventiesWM) \
|
||||
X(aventieshca,T1_bit, HeatCostAllocationMeter, AVENTIESHCA, AventiesHCA) \
|
||||
X(bfw240radio,T1_bit, HeatCostAllocationMeter, BFW240RADIO, BFW240Radio) \
|
||||
X(cma12w, C1_bit|T1_bit, TempHygroMeter, CMA12W, CMa12w) \
|
||||
|
@ -299,7 +299,8 @@ struct FieldInfo
|
|||
function<void(Unit,double)> set_value_double,
|
||||
function<void(string)> set_value_string,
|
||||
function<bool(FieldInfo*, Meter *mi, Telegram *t)> extract_double,
|
||||
function<bool(FieldInfo*, Meter *mi, Telegram *t)> extract_string
|
||||
function<bool(FieldInfo*, Meter *mi, Telegram *t)> extract_string,
|
||||
Translate::Lookup lookup
|
||||
) :
|
||||
vname_(vname),
|
||||
xuantity_(xuantity),
|
||||
|
@ -321,7 +322,8 @@ struct FieldInfo
|
|||
set_value_double_(set_value_double),
|
||||
set_value_string_(set_value_string),
|
||||
extract_double_(extract_double),
|
||||
extract_string_(extract_string)
|
||||
extract_string_(extract_string),
|
||||
lookup_(lookup)
|
||||
{}
|
||||
|
||||
string vname() { return vname_; }
|
||||
|
@ -354,6 +356,8 @@ struct FieldInfo
|
|||
string renderJson(vector<Unit> *additional_conversions);
|
||||
string renderJsonText();
|
||||
|
||||
Translate::Lookup& lookup() { return lookup_; }
|
||||
|
||||
private:
|
||||
|
||||
string vname_; // Value name, like: total current previous target
|
||||
|
@ -378,6 +382,7 @@ private:
|
|||
function<void(string)> set_value_string_; // Call back to set the value string in the c++ object
|
||||
function<bool(FieldInfo*, Meter *mi, Telegram *t)> extract_double_; // Extract field from telegram and insert into meter.
|
||||
function<bool(FieldInfo*, Meter *mi, Telegram *t)> extract_string_; // Extract field from telegram and insert into meter.
|
||||
Translate::Lookup lookup_;
|
||||
};
|
||||
|
||||
struct BusManager;
|
||||
|
|
|
@ -88,8 +88,8 @@ protected:
|
|||
void addPrint(string vname, Quantity vquantity,
|
||||
function<std::string()> getValueFunc, string help, bool field, bool json);
|
||||
|
||||
#define SET_FUNC(varname,to_unit) {[&](Unit from_unit, double d){varname = convert(d, from_unit, to_unit);}}
|
||||
#define GET_FUNC(varname,from_unit) {[&](Unit to_unit){return convert(varname, from_unit, to_unit);}}
|
||||
#define SET_FUNC(varname,to_unit) {[=](Unit from_unit, double d){varname = convert(d, from_unit, to_unit);}}
|
||||
#define GET_FUNC(varname,from_unit) {[=](Unit to_unit){return convert(varname, from_unit, to_unit);}}
|
||||
|
||||
void addFieldWithExtractor(
|
||||
string vname, // Name of value without unit, eg total
|
||||
|
@ -106,8 +106,8 @@ protected:
|
|||
function<void(Unit,double)> setValueFunc, // Use the SET macro above.
|
||||
function<double(Unit)> getValueFunc); // Use the GET macro above.
|
||||
|
||||
#define SET_STRING_FUNC(varname) {[&](string s){varname = s;}}
|
||||
#define GET_STRING_FUNC(varname) {[&](){return varname; }}
|
||||
#define SET_STRING_FUNC(varname) {[=](string s){varname = s;}}
|
||||
#define GET_STRING_FUNC(varname) {[=](){return varname; }}
|
||||
|
||||
void addStringFieldWithExtractor(
|
||||
string vname, // Name of value without unit, eg total
|
||||
|
@ -123,11 +123,20 @@ protected:
|
|||
function<void(string)> setValueFunc, // Use the SET_STRING macro above.
|
||||
function<string()> getValueFunc); // Use the GET_STRING macro above.
|
||||
|
||||
// Decode a bit field and print
|
||||
void addPrintTextFromBits(string vname, // Name of field, no suffix unit added since it is text.
|
||||
string help, // An explanation of the field.
|
||||
int props, // json,field,important
|
||||
function<std::string(MeterCommonImplementation*)> getValueFunc);
|
||||
void addStringFieldWithExtractorAndLookup(
|
||||
string vname, // Name of value without unit, eg total
|
||||
Quantity vquantity, // Value belongs to this quantity.
|
||||
DifVifKey dif_vif_key, // You can hardocde a dif vif header here or use NoDifVifKey
|
||||
MeasurementType mt, // If not using a hardcoded key, search for mt,vi,s,t and i instead.
|
||||
ValueInformation vi,
|
||||
StorageNr s,
|
||||
TariffNr t,
|
||||
IndexNr i,
|
||||
int print_properties, // Should this be printed by default in fields,json and hr.
|
||||
string help,
|
||||
function<void(string)> setValueFunc, // Use the SET_STRING macro above.
|
||||
function<string()> getValueFunc, // Use the GET_STRING macro above.
|
||||
Translate::Lookup lookup); // Translate the bits/indexes.
|
||||
|
||||
// The default implementation of poll does nothing.
|
||||
// Override for mbus meters that need to be queried and likewise for C2/T2 wmbus-meters.
|
||||
|
|
|
@ -97,3 +97,5 @@ string Lookup::translate(uint64_t bits)
|
|||
while (s.back() == ' ') s.pop_back();
|
||||
return s;
|
||||
}
|
||||
|
||||
Lookup NoLookup = {};
|
||||
|
|
|
@ -49,7 +49,10 @@ namespace Translate
|
|||
std::vector<Rule> rules;
|
||||
|
||||
std::string translate(uint64_t bits);
|
||||
bool hasLookups() { return rules.size() > 0; }
|
||||
};
|
||||
};
|
||||
|
||||
extern Translate::Lookup NoLookup;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -8,18 +8,14 @@ TEST=testoutput
|
|||
TESTNAME="Test unix timestamp in fields"
|
||||
TESTRESULT="ERROR"
|
||||
|
||||
METERS="Votten aventieswm 61070071 A004EB23329A477F1DD2D7820B56EB3D"
|
||||
METERS="Votten aventieswm 61070071 A004EB23329A477F1DD2D7820B56EB3D"
|
||||
|
||||
cat simulations/simulation_unix_timestamp.txt | grep '^{' > $TEST/test_expected.txt
|
||||
|
||||
# Wait for the second to switch before starting the run. This will avoid spurious errors
|
||||
# where the second barrier switches inside the test.
|
||||
PREV=$(date +%s)
|
||||
NOW=$PREV
|
||||
while [ "$NOW" = "$PREV" ] ; do NOW=$(date "+%s") ; done
|
||||
NOW=$(date +%s)
|
||||
|
||||
cat simulations/simulation_unix_timestamp.txt | grep '^|' | sed 's/^|//' | sed "s/UT/${NOW}/" > $TEST/test_expected.txt
|
||||
$PROG --format=fields --separator='*' --field_extra=extra_info --selectfields=total_m3,timestamp_ut,timestamp_utc,timestamp_lt,name,id,extra simulations/simulation_t1.txt $METERS > $TEST/test_output.txt 2> $TEST/test_stderr.txt
|
||||
$PROG --format=fields --separator='*' --field_extra=extra_info --selectfields=total_m3,timestamp_ut,timestamp_utc,timestamp_lt,name,id,extra simulations/simulation_unix_timestamp.txt $METERS > $TEST/test_output.txt 2> $TEST/test_stderr.txt
|
||||
|
||||
if [ "$?" = "0" ]
|
||||
then
|
||||
|
|
Ładowanie…
Reference in New Issue