Refactor aventieshca.

pull/451/head
Fredrik Öhrström 2022-01-18 09:54:58 +01:00
rodzic 3ced1753d9
commit 099bc33602
4 zmienionych plików z 100 dodań i 220 usunięć

Wyświetl plik

@ -1,5 +1,5 @@
/*
Copyright (C) 2019-2020 Fredrik Öhrström
Copyright (C) 2019-2022 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
@ -21,235 +21,117 @@
#include"wmbus.h"
#include"wmbus_utils.h"
struct MeterAventiesHCA : public virtual MeterCommonImplementation {
MeterAventiesHCA(MeterInfo &mi);
double currentConsumption(Unit u);
string setDate();
double consumptionAtSetDate(Unit u);
struct MeterAventiesHCA : public virtual MeterCommonImplementation
{
MeterAventiesHCA(MeterInfo &mi, DriverInfo &di);
private:
void processContent(Telegram *t);
string errorFlagsHumanReadable();
double current_consumption_hca_ {};
string set_date_; // The set date for index 0 below, is only sent for short telegrams.
// Ie for long telegrams with 17 values, then the set_date_ is empty.
double consumption_at_set_date_hca_[17]; // 1 to 17 store in index 0 to 16
uint16_t error_flags_;
double consumption_at_set_date_hca_[17] {}; // storagenr 1 to 17 are stored in index 0 to 16
string error_flags_;
};
MeterAventiesHCA::MeterAventiesHCA(MeterInfo &mi) :
MeterCommonImplementation(mi, "aventieshca")
static bool ok = registerDriver([](DriverInfo&di)
{
setMeterType(MeterType::HeatCostAllocationMeter);
di.setName("aventieshca");
di.setMeterType(MeterType::HeatCostAllocationMeter);
di.setExpectedTPLSecurityMode(TPLSecurityMode::AES_CBC_IV);
di.addLinkMode(LinkMode::T1);
di.addDetection(MANUFACTURER_AAA, 0x08, 0x55);
di.setConstructor([](MeterInfo& mi, DriverInfo& di){ return shared_ptr<Meter>(new MeterAventiesHCA(mi, di)); });
});
setExpectedTPLSecurityMode(TPLSecurityMode::AES_CBC_IV);
MeterAventiesHCA::MeterAventiesHCA(MeterInfo &mi, DriverInfo &di) : MeterCommonImplementation(mi, di)
{
addFieldWithExtractor(
"current_consumption",
Quantity::HCA,
NoDifVifKey,
VifScaling::Auto,
MeasurementType::Instantaneous,
ValueInformation::HeatCostAllocation,
StorageNr(0),
TariffNr(0),
IndexNr(1),
PrintProperty::JSON | PrintProperty::FIELD | PrintProperty::IMPORTANT,
"The current heat cost allocation.",
SET_FUNC(current_consumption_hca_, Unit::HCA),
GET_FUNC(current_consumption_hca_, Unit::HCA));
addLinkMode(LinkMode::T1);
addFieldWithExtractor(
"consumption_at_set_date",
Quantity::HCA,
NoDifVifKey,
VifScaling::Auto,
MeasurementType::Instantaneous,
ValueInformation::HeatCostAllocation,
StorageNr(1),
TariffNr(0),
IndexNr(1),
PrintProperty::JSON,
"Heat cost allocation at the most recent billing period date.",
SET_FUNC(consumption_at_set_date_hca_[0], Unit::HCA),
GET_FUNC(consumption_at_set_date_hca_[0], Unit::HCA));
addPrint("current_consumption", Quantity::HCA,
[&](Unit u){ return currentConsumption(u); },
"The current heat cost allocation.",
true, true);
addPrint("set_date", Quantity::Text,
[&](){ return setDate(); },
"The most recent billing period date.",
true, true);
addPrint("consumption_at_set_date", Quantity::HCA,
[&](Unit u){ return consumption_at_set_date_hca_[0]; },
"Heat cost allocation at the most recent billing period date.",
false, true);
for (int i=1; i<=17; ++i)
for (int i=2; i<=17; ++i)
{
string msg, info;
strprintf(msg, "consumption_at_set_date_%d", i);
string key, info;
strprintf(key, "consumption_at_set_date_%d", i);
strprintf(info, "Heat cost allocation at the %d billing period date.", i);
addPrint(msg, Quantity::HCA,
[this,i](Unit u){ return consumption_at_set_date_hca_[i-1]; },
info,
false, true);
addFieldWithExtractor(
key,
Quantity::HCA,
NoDifVifKey,
VifScaling::Auto,
MeasurementType::Instantaneous,
ValueInformation::HeatCostAllocation,
StorageNr(i),
TariffNr(0),
IndexNr(1),
PrintProperty::JSON,
info,
SET_FUNC(consumption_at_set_date_hca_[i-1], Unit::HCA),
GET_FUNC(consumption_at_set_date_hca_[i-1], Unit::HCA));
}
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" }
}
},
},
}
);
}
shared_ptr<Meter> createAventiesHCA(MeterInfo &mi)
{
return shared_ptr<Meter>(new MeterAventiesHCA(mi));
}
double MeterAventiesHCA::currentConsumption(Unit u)
{
return current_consumption_hca_;
}
string MeterAventiesHCA::setDate()
{
return set_date_;
}
double MeterAventiesHCA::consumptionAtSetDate(Unit u)
{
return consumption_at_set_date_hca_[0];
}
string MeterAventiesHCA::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;
}
void MeterAventiesHCA::processContent(Telegram *t)
{
// These meters can be configured to send long telegrams 18 measurement values, no date.
// or short telegrams 2 measurement values, with a date.
// Here is a long telegram:
// (aventieshca) 00: 76 length (118 bytes)
// (aventieshca) 01: 44 dll-c (from meter SND_NR)
// (aventieshca) 02: 2104 dll-mfct (AAA)
// (aventieshca) 04: 34019060 dll-id (60900134)
// (aventieshca) 08: 55 dll-version
// (aventieshca) 09: 08 dll-type (Heat Cost Allocator)
// (aventieshca) 0a: 72 tpl-ci-field (EN 13757-3 Application Layer (long tplh))
// (aventieshca) 0b: 34019060 tpl-id (60900134)
// (aventieshca) 0f: 2104 tpl-mfct (AAA)
// (aventieshca) 11: 55 tpl-version
// (aventieshca) 12: 08 tpl-type (Heat Cost Allocator)
// (aventieshca) 13: 05 tpl-acc-field
// (aventieshca) 14: 00 tpl-sts-field (OK)
// (aventieshca) 15: 6005 tpl-cfg 0560 (AES_CBC_IV nb=6 cntn=0 ra=0 hc=0 )
// (aventieshca) 17: 2f2f decrypt check bytes
// (aventieshca) 19: 0B dif (6 digit BCD Instantaneous value)
// (aventieshca) 1a: 6E vif (Units for H.C.A.)
// (aventieshca) 1b: * 911000 current consumption (1091.000000 hca)
// (aventieshca) 1e: 42 dif (16 Bit Integer/Binary Instantaneous value storagenr=1)
// (aventieshca) 1f: 6E vif (Units for H.C.A.)
// (aventieshca) 20: * 4304 consumption at set date 1 (1091.000000 hca)
// (aventieshca) 22: 82 dif (16 Bit Integer/Binary Instantaneous value)
// (aventieshca) 23: 01 dife (subunit=0 tariff=0 storagenr=2)
// (aventieshca) 24: 6E vif (Units for H.C.A.)
// (aventieshca) 25: * 3C04 consumption at set date 2 (1084.000000 hca)
// (aventieshca) 27: C2 dif (16 Bit Integer/Binary Instantaneous value storagenr=1)
// (aventieshca) 28: 01 dife (subunit=0 tariff=0 storagenr=3)
// (aventieshca) 29: 6E vif (Units for H.C.A.)
// (aventieshca) 2a: * CC03 consumption at set date 3 (972.000000 hca)
// (aventieshca) 2c: 82 dif (16 Bit Integer/Binary Instantaneous value)
// (aventieshca) 2d: 02 dife (subunit=0 tariff=0 storagenr=4)
// (aventieshca) 2e: 6E vif (Units for H.C.A.)
// (aventieshca) 2f: * 1E03 consumption at set date 4 (798.000000 hca)
// (aventieshca) 31: C2 dif (16 Bit Integer/Binary Instantaneous value storagenr=1)
// (aventieshca) 32: 02 dife (subunit=0 tariff=0 storagenr=5)
// (aventieshca) 33: 6E vif (Units for H.C.A.)
// (aventieshca) 34: * 3402 consumption at set date 5 (564.000000 hca)
// (aventieshca) 36: 82 dif (16 Bit Integer/Binary Instantaneous value)
// (aventieshca) 37: 03 dife (subunit=0 tariff=0 storagenr=6)
// (aventieshca) 38: 6E vif (Units for H.C.A.)
// (aventieshca) 39: * 3101 consumption at set date 6 (305.000000 hca)
// (aventieshca) 3b: C2 dif (16 Bit Integer/Binary Instantaneous value storagenr=1)
// (aventieshca) 3c: 03 dife (subunit=0 tariff=0 storagenr=7)
// (aventieshca) 3d: 6E vif (Units for H.C.A.)
// (aventieshca) 3e: * F701 consumption at set date 7 (503.000000 hca)
// (aventieshca) 40: 82 dif (16 Bit Integer/Binary Instantaneous value)
// (aventieshca) 41: 04 dife (subunit=0 tariff=0 storagenr=8)
// (aventieshca) 42: 6E vif (Units for H.C.A.)
// (aventieshca) 43: * FD00 consumption at set date 8 (253.000000 hca)
// (aventieshca) 45: C2 dif (16 Bit Integer/Binary Instantaneous value storagenr=1)
// (aventieshca) 46: 04 dife (subunit=0 tariff=0 storagenr=9)
// (aventieshca) 47: 6E vif (Units for H.C.A.)
// (aventieshca) 48: * 6F00 consumption at set date 9 (111.000000 hca)
// (aventieshca) 4a: 82 dif (16 Bit Integer/Binary Instantaneous value)
// (aventieshca) 4b: 05 dife (subunit=0 tariff=0 storagenr=10)
// (aventieshca) 4c: 6E vif (Units for H.C.A.)
// (aventieshca) 4d: * 4100 consumption at set date 10 (65.000000 hca)
// (aventieshca) 4f: C2 dif (16 Bit Integer/Binary Instantaneous value storagenr=1)
// (aventieshca) 50: 05 dife (subunit=0 tariff=0 storagenr=11)
// (aventieshca) 51: 6E vif (Units for H.C.A.)
// (aventieshca) 52: * 3E00 consumption at set date 11 (62.000000 hca)
// (aventieshca) 54: 82 dif (16 Bit Integer/Binary Instantaneous value)
// (aventieshca) 55: 06 dife (subunit=0 tariff=0 storagenr=12)
// (aventieshca) 56: 6E vif (Units for H.C.A.)
// (aventieshca) 57: * 3E00 consumption at set date 12 (62.000000 hca)
// (aventieshca) 59: C2 dif (16 Bit Integer/Binary Instantaneous value storagenr=1)
// (aventieshca) 5a: 06 dife (subunit=0 tariff=0 storagenr=13)
// (aventieshca) 5b: 6E vif (Units for H.C.A.)
// (aventieshca) 5c: * 3E00 consumption at set date 13 (62.000000 hca)
// (aventieshca) 5e: 82 dif (16 Bit Integer/Binary Instantaneous value)
// (aventieshca) 5f: 07 dife (subunit=0 tariff=0 storagenr=14)
// (aventieshca) 60: 6E vif (Units for H.C.A.)
// (aventieshca) 61: * 3E00 consumption at set date 14 (62.000000 hca)
// (aventieshca) 63: C2 dif (16 Bit Integer/Binary Instantaneous value storagenr=1)
// (aventieshca) 64: 07 dife (subunit=0 tariff=0 storagenr=15)
// (aventieshca) 65: 6E vif (Units for H.C.A.)
// (aventieshca) 66: * 3E00 consumption at set date 15 (62.000000 hca)
// (aventieshca) 68: 82 dif (16 Bit Integer/Binary Instantaneous value)
// (aventieshca) 69: 08 dife (subunit=0 tariff=0 storagenr=16)
// (aventieshca) 6a: 6E vif (Units for H.C.A.)
// (aventieshca) 6b: * 3D00 consumption at set date 16 (61.000000 hca)
// (aventieshca) 6d: C2 dif (16 Bit Integer/Binary Instantaneous value storagenr=1)
// (aventieshca) 6e: 08 dife (subunit=0 tariff=0 storagenr=17)
// (aventieshca) 6f: 6E vif (Units for H.C.A.)
// (aventieshca) 70: * 3500 consumption at set date 17 (53.000000 hca)
// (aventieshca) 72: 02 dif (16 Bit Integer/Binary Instantaneous value)
// (aventieshca) 73: FD vif (Second extension FD of VIF-codes)
// (aventieshca) 74: 17 vife (Error flags (binary))
// (aventieshca) 75: * 0000 error flags (0000)
int offset;
string key;
if (findKey(MeasurementType::Unknown, ValueInformation::HeatCostAllocation, 0, 0, &key, &t->values))
{
extractDVdouble(&t->values, key, &offset, &current_consumption_hca_);
t->addMoreExplanation(offset, " current consumption (%f hca)", current_consumption_hca_);
}
if (findKey(MeasurementType::Unknown, ValueInformation::Date, 1, 0, &key, &t->values)) {
struct tm date;
extractDVdate(&t->values, key, &offset, &date);
set_date_ = strdate(&date);
t->addMoreExplanation(offset, " set date (%s)", set_date_.c_str());
}
for (int i=1; i<=17; ++i)
{
if (findKey(MeasurementType::Unknown, ValueInformation::HeatCostAllocation, i, 0, &key, &t->values))
{
string info;
strprintf(info, " consumption at set date %d (%%f hca)", i);
extractDVdouble(&t->values, key, &offset, &consumption_at_set_date_hca_[i-1]);
t->addMoreExplanation(offset, info.c_str(), consumption_at_set_date_hca_[i-1]);
}
}
key = "02FD17";
if (hasKey(&t->values, key)) {
extractDVuint16(&t->values, "02FD17", &offset, &error_flags_);
t->addMoreExplanation(offset, " error flags (%04X)", error_flags_);
}
}
// Test: HCA aventieshca 60900126 NOKEY
// telegram=|76442104260190605508722601906021045508060060052F2F#0B6E660100426EA60082016EA600C2016E9E0082026E7E00C2026E5B0082036E4200C2036E770182046E5B01C2046E4C0182056E4701C2056E3E0182066E3B01C2066E3B0182076E3B01C2076E3B0182086E1301C2086E9C0002FD170000|
// {"media":"heat cost allocation","meter":"aventieshca","name":"HCA","id":"60900126","current_consumption_hca":166,"consumption_at_set_date_hca":166,"consumption_at_set_date_2_hca":166,"consumption_at_set_date_3_hca":158,"consumption_at_set_date_4_hca":126,"consumption_at_set_date_5_hca":91,"consumption_at_set_date_6_hca":66,"consumption_at_set_date_7_hca":375,"consumption_at_set_date_8_hca":347,"consumption_at_set_date_9_hca":332,"consumption_at_set_date_10_hca":327,"consumption_at_set_date_11_hca":318,"consumption_at_set_date_12_hca":315,"consumption_at_set_date_13_hca":315,"consumption_at_set_date_14_hca":315,"consumption_at_set_date_15_hca":315,"consumption_at_set_date_16_hca":275,"consumption_at_set_date_17_hca":156,"error_flags":"","timestamp":"1111-11-11T11:11:11Z"}
// |HCA;60900126;166.000000;;1111-11-11 11:11.11

Wyświetl plik

@ -22,7 +22,6 @@
// meter driver, manufacturer, media, version
//
#define METER_DETECTION \
X(AVENTIESHCA,MANUFACTURER_AAA, 0x08, 0x55) \
X(APATOR162, MANUFACTURER_APA, 0x06, 0x05) \
X(APATOR162, MANUFACTURER_APA, 0x07, 0x05) \
X(BFW240RADIO, MANUFACTURER_BFW,0x08, 0x02) \

Wyświetl plik

@ -1,5 +1,5 @@
/*
Copyright (C) 2021 Fredrik Öhrström
Copyright (C) 2021-2022 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

Wyświetl plik

@ -52,7 +52,6 @@ LIST_OF_METER_TYPES
X(auto, 0, AutoMeter, AUTO, Auto) \
X(unknown, 0, UnknownMeter, UNKNOWN, Unknown) \
X(apator162, C1_bit|T1_bit, WaterMeter, APATOR162, Apator162) \
X(aventieshca,T1_bit, HeatCostAllocationMeter, AVENTIESHCA, AventiesHCA) \
X(bfw240radio,T1_bit, HeatCostAllocationMeter, BFW240RADIO, BFW240Radio) \
X(cma12w, C1_bit|T1_bit, TempHygroMeter, CMA12W, CMa12w) \
X(compact5, T1_bit, HeatMeter, COMPACT5, Compact5) \