kopia lustrzana https://github.com/weetmuts/wmbusmeters
Clean up tpl status reporting.
rodzic
07754197fc
commit
bda349bcd2
|
@ -8,7 +8,7 @@ telegram=|244465323251839134087a4f0000000b6e0403004b6e660300426c9e29326cffff046d
|
|||
# Test another HCA from Qundis
|
||||
|
||||
telegram=|294465324185990401087a0080000082046c7f018b046e210300046d1a0e6f0202fdac7e012301fd0c01|
|
||||
{"media":"heat cost allocation","meter":"lse_08","name":"HCA2","id":"04998541","status":"TPL_MFCT_80","set_date":"2003-01-31","consumption_at_set_date_hca":321,"device_date_time":"2003-02-15 14:26","duration_since_readout_h":2.489167,"model_version":"01","timestamp":"1111-11-11T11:11:11Z"}
|
||||
{"media":"heat cost allocation","meter":"lse_08","name":"HCA2","id":"04998541","status":"UNKNOWN_80","set_date":"2003-01-31","consumption_at_set_date_hca":321,"device_date_time":"2003-02-15 14:26","duration_since_readout_h":2.489167,"model_version":"01","timestamp":"1111-11-11T11:11:11Z"}
|
||||
|HCA2;04998541;2003-01-31;321;1111-11-11 11:11.11
|
||||
|
||||
# Test Qundis QWater5.5 S1 meter.
|
||||
|
|
|
@ -295,7 +295,7 @@ telegram=|6044B8059430040001037A1D005085E2B670BCF1A5C87E0C1A51DA18924EF984613DA2
|
|||
|
||||
# Test Hydrocal M3 heat/cooling meter
|
||||
telegram=|8E44B409747372710B0D7A798080052F2F_0C0E59600100046D1D36B9290C13679947000C0E000000000C13590000000C13000000000C13000000000A5A18020A5E11020F823D06003D06003D06003D0600140600620500480400E402001601000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002F2F|
|
||||
{"media":"heat/cooling load","meter":"hydrocalm3","name":"HeatCool","id":"71727374","status": "TPL_MFCT_80","total_heating_kwh":4460.833333,"total_cooling_kwh":0,"device_datetime":"2021-09-25 22:29","total_heating_m3":479.967,"total_cooling_m3":0.059,"c1_volume_m3":0,"c2_volume_m3":0,"supply_temperature_c":21.8,"return_temperature_c":21.1,"timestamp":"1111-11-11T11:11:11Z"}
|
||||
{"media":"heat/cooling load","meter":"hydrocalm3","name":"HeatCool","id":"71727374","status": "SABOTAGE_ENCLOSURE","total_heating_kwh":4460.833333,"total_cooling_kwh":0,"device_datetime":"2021-09-25 22:29","total_heating_m3":479.967,"total_cooling_m3":0.059,"c1_volume_m3":0,"c2_volume_m3":0,"supply_temperature_c":21.8,"return_temperature_c":21.1,"timestamp":"1111-11-11T11:11:11Z"}
|
||||
|HeatCool;71727374;4460.833333;2021-09-25 22:29;1111-11-11 11:11.11
|
||||
|
||||
# Test Weptech Munia temperature hygrometer
|
||||
|
|
|
@ -31,19 +31,11 @@ namespace
|
|||
di.addLinkMode(LinkMode::T1);
|
||||
di.addDetection(MANUFACTURER_EIE, 0x1a, 0x0c);
|
||||
di.addMfctTPLStatusBits(
|
||||
{
|
||||
{
|
||||
{
|
||||
"TPL_STS",
|
||||
Translate::Type::BitToString,
|
||||
AlwaysTrigger, MaskBits(0xe0), // Always use 0xe0 for tpl mfct status bits.
|
||||
"OK",
|
||||
{
|
||||
{ 0x40, "RTC_INVALID" }
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
Translate::Lookup()
|
||||
.add(Translate::Rule("TPL_STS", Translate::Type::BitToString)
|
||||
.set(MaskBits(0xe0))
|
||||
.set(DefaultMessage("OK"))
|
||||
.add(Translate::Map(0x04 ,"RTC_INVALID", TestBit::Set))));
|
||||
di.setConstructor([](MeterInfo& mi, DriverInfo& di){ return shared_ptr<Meter>(new Driver(mi, di)); });
|
||||
});
|
||||
|
||||
|
|
|
@ -30,19 +30,6 @@ namespace
|
|||
di.setDefaultFields("name,id,total_energy_consumption_kwh,current_power_consumption_kw,total_volume_m3,flow_temperature_c,return_temperature_c,external_temperature_c,status,timestamp");
|
||||
di.setMeterType(MeterType::HeatMeter);
|
||||
di.addDetection(MANUFACTURER_APA, 0x04, 0x40);
|
||||
di.addMfctTPLStatusBits(
|
||||
{
|
||||
{
|
||||
{
|
||||
"TPL_STS",
|
||||
Translate::Type::BitToString,
|
||||
AlwaysTrigger, MaskBits(0xe0), // Always use 0xe0 for tpl mfct status bits.
|
||||
"OK",
|
||||
{
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
di.setConstructor([](MeterInfo& mi, DriverInfo& di){ return shared_ptr<Meter>(new Driver(mi, di)); });
|
||||
});
|
||||
|
||||
|
|
|
@ -31,6 +31,12 @@ namespace
|
|||
di.setMeterType(MeterType::HeatMeter);
|
||||
di.addLinkMode(LinkMode::T1);
|
||||
di.addDetection(MANUFACTURER_BMT, 0x0d, 0x0b);
|
||||
di.addMfctTPLStatusBits(
|
||||
Translate::Lookup()
|
||||
.add(Translate::Rule("TPL_STS", Translate::Type::BitToString)
|
||||
.set(MaskBits(0xe0))
|
||||
.set(DefaultMessage("OK"))
|
||||
.add(Translate::Map(0x80 ,"SABOTAGE_ENCLOSURE", TestBit::Set))));
|
||||
di.setConstructor([](MeterInfo& mi, DriverInfo& di){ return shared_ptr<Meter>(new Driver(mi, di)); });
|
||||
});
|
||||
|
||||
|
@ -153,5 +159,5 @@ namespace
|
|||
|
||||
// Test:HeatCool hydrocalm3 71727374 NOKEY
|
||||
// telegram=|8E44B409747372710B0D7A798080052F2F_0C0E59600100046D1D36B9290C13679947000C0E000000000C13590000000C13000000000C13000000000A5A18020A5E11020F823D06003D06003D06003D0600140600620500480400E402001601000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002F2F|
|
||||
// {"media":"heat/cooling load","meter":"hydrocalm3","name":"HeatCool","id":"71727374","status": "TPL_MFCT_80","total_heating_kwh":4460.833333,"total_cooling_kwh":0,"device_datetime":"2021-09-25 22:29","total_heating_m3":479.967,"total_cooling_m3":0.059,"c1_volume_m3":0,"c2_volume_m3":0,"supply_temperature_c":21.8,"return_temperature_c":21.1,"timestamp":"1111-11-11T11:11:11Z"}
|
||||
// {"media":"heat/cooling load","meter":"hydrocalm3","name":"HeatCool","id":"71727374","status": "SABOTAGE_ENCLOSURE","total_heating_kwh":4460.833333,"total_cooling_kwh":0,"device_datetime":"2021-09-25 22:29","total_heating_m3":479.967,"total_cooling_m3":0.059,"c1_volume_m3":0,"c2_volume_m3":0,"supply_temperature_c":21.8,"return_temperature_c":21.1,"timestamp":"1111-11-11T11:11:11Z"}
|
||||
// |HeatCool;71727374;4460.833333;2021-09-25 22:29;1111-11-11 11:11.11
|
||||
|
|
|
@ -33,19 +33,11 @@ namespace
|
|||
di.addDetection(MANUFACTURER_LAS, 0x00, 0x1b);
|
||||
di.addDetection(MANUFACTURER_LAS, 0x02, 0x0b);
|
||||
di.addMfctTPLStatusBits(
|
||||
{
|
||||
{
|
||||
{
|
||||
"TPL_STS",
|
||||
Translate::Type::BitToString,
|
||||
AlwaysTrigger, MaskBits(0xe0), // Always use 0xe0 for tpl mfct status bits.
|
||||
"OK",
|
||||
{
|
||||
{ 0x40, "SABOTAGE_ENCLOSURE" }
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
Translate::Lookup()
|
||||
.add(Translate::Rule("TPL_STS", Translate::Type::BitToString)
|
||||
.set(MaskBits(0xe0))
|
||||
.set(DefaultMessage("OK"))
|
||||
.add(Translate::Map(0x40 ,"SABOTAGE_ENCLOSURE", TestBit::Set))));
|
||||
di.setConstructor([](MeterInfo& mi, DriverInfo& di){ return shared_ptr<Meter>(new Driver(mi, di)); });
|
||||
});
|
||||
|
||||
|
|
|
@ -31,19 +31,11 @@ namespace
|
|||
di.setMeterType(MeterType::TempHygroMeter);
|
||||
di.addDetection(MANUFACTURER_LAS, 0x1b, 0x07);
|
||||
di.addMfctTPLStatusBits(
|
||||
{
|
||||
{
|
||||
{
|
||||
"TPL_STS",
|
||||
Translate::Type::BitToString,
|
||||
AlwaysTrigger, MaskBits(0xe0), // Always use 0xe0 for tpl mfct status bits.
|
||||
"OK",
|
||||
{
|
||||
{ 0x40, "SABOTAGE_ENCLOSURE" }
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
Translate::Lookup()
|
||||
.add(Translate::Rule("TPL_STS", Translate::Type::BitToString)
|
||||
.set(MaskBits(0xe0))
|
||||
.set(DefaultMessage("OK"))
|
||||
.add(Translate::Map(0x40 ,"SABOTAGE_ENCLOSURE", TestBit::Set))));
|
||||
di.setConstructor([](MeterInfo& mi, DriverInfo& di){ return shared_ptr<Meter>(new Driver(mi, di)); });
|
||||
});
|
||||
|
||||
|
|
|
@ -128,5 +128,5 @@ namespace
|
|||
|
||||
// Test: HCA2 lse_08 04998541 NOKEY
|
||||
// telegram=|294465324185990401087a0080000082046c7f018b046e210300046d1a0e6f0202fdac7e012301fd0c01|
|
||||
// {"media":"heat cost allocation","meter":"lse_08","name":"HCA2","id":"04998541","status":"TPL_MFCT_80","set_date":"2003-01-31","consumption_at_set_date_hca":321,"device_date_time":"2003-02-15 14:26","duration_since_readout_h":2.489167,"model_version":"01","timestamp":"1111-11-11T11:11:11Z"}
|
||||
// {"media":"heat cost allocation","meter":"lse_08","name":"HCA2","id":"04998541","status":"UNKNOWN_80","set_date":"2003-01-31","consumption_at_set_date_hca":321,"device_date_time":"2003-02-15 14:26","duration_since_readout_h":2.489167,"model_version":"01","timestamp":"1111-11-11T11:11:11Z"}
|
||||
// |HCA2;04998541;2003-01-31;321;1111-11-11 11:11.11
|
||||
|
|
|
@ -286,7 +286,7 @@ void MeterCommonImplementation::addLinkMode(LinkMode lm)
|
|||
link_modes_.addLinkMode(lm);
|
||||
}
|
||||
|
||||
void MeterCommonImplementation::addMfctTPLStatusBits(Translate::Lookup lookup)
|
||||
void MeterCommonImplementation::addMfctTPLStatusBits(Translate::Lookup &lookup)
|
||||
{
|
||||
mfct_tpl_status_bits_ = lookup;
|
||||
}
|
||||
|
|
|
@ -191,7 +191,7 @@ public:
|
|||
void setDefaultFields(string f) { default_fields_ = splitString(f, ','); }
|
||||
void addLinkMode(LinkMode lm) { linkmodes_.addLinkMode(lm); }
|
||||
void forceMfctIndex(int i) { force_mfct_index_ = i; }
|
||||
void addMfctTPLStatusBits(Translate::Lookup lookup) { mfct_tpl_status_bits_ = lookup; }
|
||||
void addMfctTPLStatusBits(Translate::Lookup &lookup) { mfct_tpl_status_bits_ = lookup; }
|
||||
void setConstructor(function<shared_ptr<Meter>(MeterInfo&,DriverInfo&)> c) { constructor_ = c; }
|
||||
void addDetection(uint16_t mfct, uchar type, uchar ver) { detect_.push_back({ mfct, type, ver }); }
|
||||
vector<DriverDetect> &detect() { return detect_; }
|
||||
|
|
|
@ -98,7 +98,7 @@ protected:
|
|||
std::vector<std::string> &meterExtraConstantFields();
|
||||
void setMeterType(MeterType mt);
|
||||
void addLinkMode(LinkMode lm);
|
||||
void addMfctTPLStatusBits(Translate::Lookup lookup);
|
||||
void addMfctTPLStatusBits(Translate::Lookup &lookup);
|
||||
|
||||
// Print with the default unit for this quantity.
|
||||
void addPrint(string vname, Quantity vquantity,
|
||||
|
|
|
@ -55,7 +55,7 @@ void handleBitToString(Rule& rule, string &out_s, uint64_t bits)
|
|||
{
|
||||
// Check that the match rule does not extend outside of the mask!
|
||||
// If mask is 0xff then a match for 0x100 will trigger this bad warning!
|
||||
string tmp = tostrprintf("BAD_RULE_%s(from=0x%x mask=0x%x)", rule.name.c_str(), m.from, rule.mask);
|
||||
string tmp = tostrprintf("BAD_RULE_%s(from=0x%x mask=0x%x)", rule.name.c_str(), m.from, mask);
|
||||
s += tmp+" ";
|
||||
}
|
||||
|
||||
|
@ -243,6 +243,22 @@ string Lookup::translate(uint64_t bits)
|
|||
return sortStatusString(total);
|
||||
}
|
||||
|
||||
string Lookup::str()
|
||||
{
|
||||
string x = " Lookup {\n";
|
||||
|
||||
for (Rule& r : rules)
|
||||
{
|
||||
x += " Rulex {\n";
|
||||
x += " name = "+r.name+"\n";
|
||||
x += " }\n";
|
||||
}
|
||||
|
||||
x += "}\n";
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
Lookup NoLookup = {};
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (C) 2021 Fredrik Öhrström (gpl-3.0-or-later)
|
||||
Copyright (C) 2021-2022 Fredrik Öhrström (gpl-3.0-or-later)
|
||||
|
||||
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
|
||||
|
@ -111,6 +111,8 @@ namespace Translate
|
|||
bool hasLookups() { return rules.size() > 0; }
|
||||
|
||||
Lookup &add(Rule r) { rules.push_back(r); return *this; }
|
||||
|
||||
std::string str();
|
||||
};
|
||||
};
|
||||
|
||||
|
|
57
src/wmbus.cc
57
src/wmbus.cc
|
@ -1439,9 +1439,9 @@ bool Telegram::parseShortTPL(std::vector<uchar>::iterator &pos)
|
|||
|
||||
CHECK(1);
|
||||
tpl_sts = *pos;
|
||||
tpl_sts_offset = distance(frame.begin(), pos);
|
||||
addExplanationAndIncrementPos(pos, 1, KindOfData::PROTOCOL, Understanding::FULL,
|
||||
"%02x tpl-sts-field (%s)", tpl_sts, decodeTPLStatusByteWithLookup(tpl_sts, NULL).c_str());
|
||||
|
||||
"%02x tpl-sts-field (%s)", tpl_sts, decodeTPLStatusByteOnlyStandardBits(tpl_sts).c_str());
|
||||
bool ok = parseTPLConfig(pos);
|
||||
if (!ok) return false;
|
||||
|
||||
|
@ -3962,21 +3962,6 @@ uint64_t dataAsUint64(int dif, int vif, int vife, string data)
|
|||
return -1;
|
||||
}
|
||||
|
||||
string formatData(int dif, int vif, int vife, string data)
|
||||
{
|
||||
string r;
|
||||
|
||||
int t = vif & 0x7f;
|
||||
if (t >= 0 && t <= 0x77 && !(t >= 0x6c && t<=0x6f)) {
|
||||
// These are vif codes with an understandable key and unit.
|
||||
double val = dataAsDouble(dif, vif, vife, data);
|
||||
strprintf(&r, "%d", val);
|
||||
return r;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
string linkModeName(LinkMode link_mode)
|
||||
{
|
||||
|
||||
|
@ -4980,39 +4965,8 @@ string decodeTPLStatusByteOnlyStandardBits(uchar sts)
|
|||
return s;
|
||||
}
|
||||
|
||||
string decodeTPLStatusByteWithLookup(uchar sts, map<int,string> *vendor_lookup)
|
||||
{
|
||||
string s = decodeTPLStatusByteOnlyStandardBits(sts);
|
||||
string t = "OK";
|
||||
|
||||
if ((sts & 0xe0) != 0)
|
||||
{
|
||||
t = "";
|
||||
// Vendor specific bits are set, lets translate them.
|
||||
int v = sts & 0xf8; // Zero the 3 lowest bits. Including the temp and permanent bits is wrong here.
|
||||
// But that is how it is implemented right now. This code is about to go away.
|
||||
if (vendor_lookup != NULL && vendor_lookup->count(v) != 0)
|
||||
{
|
||||
t += (*vendor_lookup)[v];
|
||||
t += " ";
|
||||
}
|
||||
else
|
||||
{
|
||||
// We could not translate, just print the bits.
|
||||
t += tostrprintf("TPL_MFCT_%02X ", sts & 0xe0);
|
||||
}
|
||||
while (t.size() > 0 && t.back() == ' ') t.pop_back();
|
||||
}
|
||||
|
||||
if (t == "OK" || t == "") return s;
|
||||
if (s == "OK" || s == "") return t;
|
||||
|
||||
return s+" "+t;
|
||||
}
|
||||
|
||||
string decodeTPLStatusByteNoMfct(uchar sts)
|
||||
{
|
||||
string s = decodeTPLStatusByteOnlyStandardBits(sts);
|
||||
string t = "OK";
|
||||
|
||||
if ((sts & 0xe0) != 0)
|
||||
|
@ -5020,10 +4974,7 @@ string decodeTPLStatusByteNoMfct(uchar sts)
|
|||
t = tostrprintf("UNKNOWN_%02X", sts & 0xe0);
|
||||
}
|
||||
|
||||
if (t == "OK" || t == "") return s;
|
||||
if (s == "OK" || s == "") return t;
|
||||
|
||||
return s+" "+t;
|
||||
return t;
|
||||
}
|
||||
|
||||
string decodeTPLStatusByteWithMfct(uchar sts, Translate::Lookup &lookup)
|
||||
|
@ -5040,7 +4991,7 @@ string decodeTPLStatusByteWithMfct(uchar sts, Translate::Lookup &lookup)
|
|||
}
|
||||
else
|
||||
{
|
||||
t = decodeTPLStatusByteWithLookup(sts & 0xe0, NULL);
|
||||
t = decodeTPLStatusByteNoMfct(sts & 0xe0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -755,7 +755,6 @@ string vifKey(int vif); // E.g. temperature energy power mass_flow volume_flow
|
|||
string vifUnit(int vif); // E.g. m3 c kwh kw MJ MJh
|
||||
string vifType(int vif); // Long description
|
||||
string vifeType(int dif, int vif, int vife); // Long description
|
||||
string formatData(int dif, int vif, int vife, string data);
|
||||
|
||||
// Decode only the standard defined bits in the tpl status byte. Ignore the top 3 bits.
|
||||
// Return "OK" if sts == 0
|
||||
|
@ -766,9 +765,6 @@ string decodeTPLStatusByteNoMfct(uchar sts);
|
|||
// Decode the standard bits and translate the top 3 bits if set.
|
||||
// Return "OK" if sts == 0
|
||||
string decodeTPLStatusByteWithMfct(uchar sts, Translate::Lookup &lookup);
|
||||
// Old style lookup to go away.
|
||||
// Return "OK" if sts == 0
|
||||
string decodeTPLStatusByteWithLookup(uchar sts, map<int,string> *vendor_lookup);
|
||||
|
||||
int difLenBytes(int dif);
|
||||
MeasurementType difMeasurementType(int dif);
|
||||
|
|
|
@ -10,6 +10,7 @@ echo "Testing drivers"
|
|||
|
||||
TESTNAME="Test driver tests"
|
||||
TESTRESULT="ERROR"
|
||||
FAILED=false
|
||||
|
||||
ALL_DRIVERS=$(cd src; echo driver_*cc)
|
||||
|
||||
|
@ -46,11 +47,15 @@ do
|
|||
then
|
||||
meld $TEST/test_expected_json.txt $TEST/test_response_json.txt
|
||||
fi
|
||||
echo "Failure: $TESTNAME"
|
||||
FAILED=true
|
||||
fi
|
||||
else
|
||||
echo "wmbusmeters returned error code: $?"
|
||||
cat $TEST/test_output_json.txt
|
||||
cat $TEST/test_stderr_json.txt
|
||||
echo "Failure: $TESTNAME"
|
||||
FAILED=true
|
||||
fi
|
||||
|
||||
cat $TEST/simulation.txt | grep '^|' | sed 's/^|//' > $TEST/test_expected_fields.txt
|
||||
|
@ -69,14 +74,18 @@ do
|
|||
then
|
||||
meld $TEST/test_expected_fields.txt $TEST/test_response_fields.txt
|
||||
fi
|
||||
echo "Failure: $TESTNAME"
|
||||
FAILED=true
|
||||
fi
|
||||
else
|
||||
echo "wmbusmeters returned error code: $?"
|
||||
cat $TEST/test_output_fields.txt
|
||||
cat $TEST/test_stderr_fields.txt
|
||||
echo "Failure: $TESTNAME"
|
||||
FAILED=true
|
||||
fi
|
||||
|
||||
if [ "$TESTRESULT" = "ERROR" ]
|
||||
if [ "$TESTRESULT" = "ERROR" ] || "$FAILED" = "true"
|
||||
then
|
||||
echo ERROR: $TESTNAME
|
||||
exit 1
|
||||
|
|
Ładowanie…
Reference in New Issue