diff --git a/src/meter_aventieshca.cc b/src/meter_aventieshca.cc index 7083470..2ad15b3 100644 --- a/src/meter_aventieshca.cc +++ b/src/meter_aventieshca.cc @@ -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(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 createAventiesHCA(MeterInfo &mi) -{ - return shared_ptr(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, ¤t_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 diff --git a/src/meter_detection.h b/src/meter_detection.h index 137aae6..171377e 100644 --- a/src/meter_detection.h +++ b/src/meter_detection.h @@ -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) \ diff --git a/src/meter_piigth.cc b/src/meter_piigth.cc index 28fe7b9..2f9b706 100644 --- a/src/meter_piigth.cc +++ b/src/meter_piigth.cc @@ -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 diff --git a/src/meters.h b/src/meters.h index f9b6b9f..a75d9c9 100644 --- a/src/meters.h +++ b/src/meters.h @@ -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) \