diff --git a/Makefile b/Makefile index 9475335..eadedd9 100644 --- a/Makefile +++ b/Makefile @@ -271,6 +271,9 @@ test: testd: @./test.sh build_debug/wmbusmeters +testdriver: + @./tests/test_drivers.sh build/wmbusmeters driver_${DRIVER}.cc + update_manufacturers: iconv -f utf-8 -t ascii//TRANSLIT -c DLMS_Flagids.csv -o tmp.flags cat tmp.flags | grep -v ^# | cut -f 1 > list.flags diff --git a/simulations/simulation_c1.txt b/simulations/simulation_c1.txt index 4032c0f..2d047f8 100644 --- a/simulations/simulation_c1.txt +++ b/simulations/simulation_c1.txt @@ -52,7 +52,7 @@ telegram=|314493449392919034087a520000200b6e9700004b6e700200426c9f2ccb086e970000 # Test CMa12w C1 telegrams telegram=|2744961566666666201B7AF9000020_2F2F02651E094265180902FD1B30030DFD0F05302E302E340F| -{"media":"room sensor","meter":"cma12w","name":"Rum","id":"66666666","current_temperature_c":23.34,"average_temperature_1h_c":23.28,"timestamp":"1111-11-11T11:11:11Z"} +{"media":"room sensor","meter":"cma12w","name":"Rum","id":"66666666","software_version":"4.0.0","status":"OK","current_temperature_c":23.34,"average_temperature_1h_c":23.28,"battery":"BATTERY_330","timestamp":"1111-11-11T11:11:11Z"} # Test Multical403 C1 telegrams, with cooling configuration diff --git a/src/driver_cma12w.cc b/src/driver_cma12w.cc new file mode 100644 index 0000000..42a2243 --- /dev/null +++ b/src/driver_cma12w.cc @@ -0,0 +1,102 @@ +/* + Copyright (C) 2020-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 + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include"meters_common_implementation.h" + +namespace +{ + struct Driver : public virtual MeterCommonImplementation + { + Driver(MeterInfo &mi, DriverInfo &di); + }; + + static bool ok = registerDriver([](DriverInfo&di) + { + di.setName("cma12w"); + di.setDefaultFields("name,id,current_temperature_c,timestamp"); + di.setMeterType(MeterType::TempHygroMeter); + di.addLinkMode(LinkMode::C1); + di.addLinkMode(LinkMode::T1); + di.addDetection(MANUFACTURER_ELV, 0x1b, 0x20); + + di.setConstructor([](MeterInfo& mi, DriverInfo& di){ return shared_ptr(new Driver(mi, di)); }); + + }); + + Driver::Driver(MeterInfo &mi, DriverInfo &di) : MeterCommonImplementation(mi, di) + { + addOptionalCommonFields(); + + addStringField( + "status", + "Meter status from tpl status field.", + PrintProperty::JSON | PrintProperty::FIELD | PrintProperty::IMPORTANT | + PrintProperty::STATUS | PrintProperty::JOIN_TPL_STATUS); + + addNumericFieldWithExtractor( + "current_temperature", + "The current temperature.", + PrintProperty::JSON | PrintProperty::FIELD, + Quantity::Temperature, + VifScaling::Auto, + FieldMatcher::build() + .set(MeasurementType::Instantaneous) + .set(VIFRange::ExternalTemperature) + ); + + addNumericFieldWithExtractor( + "average_temperature_1h", + "The average temperature over the last hour.", + PrintProperty::JSON | PrintProperty::FIELD, + Quantity::Temperature, + VifScaling::Auto, + FieldMatcher::build() + .set(MeasurementType::Instantaneous) + .set(VIFRange::ExternalTemperature) + .set(StorageNr(1)) + ); + + addStringFieldWithExtractorAndLookup( + "battery", + "Battery status.", + PrintProperty::JSON | PrintProperty::FIELD, + FieldMatcher::build() + .set(MeasurementType::Instantaneous) + .set(VIFRange::DigitalInput), + Translate::Lookup( + { + { + { + "BATTERY", + Translate::Type::BitToString, + 0xffff, + "", + { + } + }, + }, + })); + + + } +} + + +// Test: Tempo cma12w 66666666 NOKEY +// telegram=|2744961566666666201B7AF9000020_2F2F02651E094265180902FD1B30030DFD0F05302E302E340F| +// {"media":"room sensor","meter":"cma12w","name":"Tempo","id":"66666666","software_version":"4.0.0","status":"OK","current_temperature_c":23.34,"average_temperature_1h_c":23.28,"battery":"BATTERY_330","timestamp":"1111-11-11T11:11:11Z"} +// |Tempo;66666666;23.34;1111-11-11 11:11.11 diff --git a/src/dvparser.h b/src/dvparser.h index 3c4df1d..6b5fbf4 100644 --- a/src/dvparser.h +++ b/src/dvparser.h @@ -53,6 +53,7 @@ X(ModelVersion,0x7D0C,0x7D0C, Quantity::Text, Unit::TXT) \ X(SoftwareVersion,0x7D0F,0x7D0F, Quantity::Text, Unit::TXT) \ X(ErrorFlags,0x7D17,0x7D17, Quantity::Text, Unit::TXT) \ + X(DigitalInput,0x7D1B,0x7D1B, Quantity::Text, Unit::TXT) \ X(DurationOfTariff,0x7D31,0x7D33, Quantity::Time, Unit::Hour) \ X(Dimensionless,0x7D3A,0x7D3A, Quantity::Counter, Unit::COUNTER) \ X(Voltage,0x7D40,0x7D4F, Quantity::Voltage, Unit::Volt) \ diff --git a/src/meter_cma12w.cc b/src/meter_cma12w.cc deleted file mode 100644 index 7d5c693..0000000 --- a/src/meter_cma12w.cc +++ /dev/null @@ -1,112 +0,0 @@ -/* - Copyright (C) 2020 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 - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include"dvparser.h" -#include"meters.h" -#include"meters_common_implementation.h" -#include"wmbus.h" -#include"wmbus_utils.h" - -struct MeterCMa12w : public virtual MeterCommonImplementation { - MeterCMa12w(MeterInfo &mi); - - double currentTemperature(Unit u); - double currentRelativeHumidity(); - -private: - - void processContent(Telegram *t); - - double current_temperature_c_ {}; - double average_temperature_1h_c_; -}; - -MeterCMa12w::MeterCMa12w(MeterInfo &mi) : - MeterCommonImplementation(mi, "cma12w") -{ - setMeterType(MeterType::TempHygroMeter); - - setExpectedTPLSecurityMode(TPLSecurityMode::AES_CBC_IV); - - addLinkMode(LinkMode::T1); - - addPrint("current_temperature", Quantity::Temperature, - [&](Unit u){ return currentTemperature(u); }, - "The current temperature.", - PrintProperty::FIELD | PrintProperty::JSON); - - addPrint("average_temperature_1h", Quantity::Temperature, - [&](Unit u){ return convert(average_temperature_1h_c_, Unit::C, u); }, - "The average temperature over the last hour.", - PrintProperty::JSON); -} - -shared_ptr createCMa12w(MeterInfo &mi) -{ - return shared_ptr(new MeterCMa12w(mi)); -} - -double MeterCMa12w::currentTemperature(Unit u) -{ - assertQuantity(u, Quantity::Temperature); - return convert(current_temperature_c_, Unit::C, u); -} - -double MeterCMa12w::currentRelativeHumidity() -{ - return 0.0; -} - -void MeterCMa12w::processContent(Telegram *t) -{ - /* - (cma12w) 0f: 2F skip - (cma12w) 10: 2F skip - (cma12w) 11: 02 dif (16 Bit Integer/Binary Instantaneous value) - (cma12w) 12: 65 vif (External temperature 10⁻² °C) - (cma12w) 13: * 1E09 current temperature (23.340000 C) - (cma12w) 15: 42 dif (16 Bit Integer/Binary Instantaneous value storagenr=1) - (cma12w) 16: 65 vif (External temperature 10⁻² °C) - (cma12w) 17: * 1809 average temperature 1h (23.280000 C)) - (cma12w) 19: 02 dif (16 Bit Integer/Binary Instantaneous value) - (cma12w) 1a: FD vif (Second extension of VIF-codes) - (cma12w) 1b: 1B vife (Digital Input (binary)) - (cma12w) 1c: 3003 - (cma12w) 1e: 0D dif (variable length Instantaneous value) - (cma12w) 1f: FD vif (Second extension of VIF-codes) - (cma12w) 20: 0F vife (Software version #) - (cma12w) 21: 05 varlen=5 - (cma12w) 22: 302E302E34 - A single 0f at the end!? - */ - - int offset; - string key; - - if (findKey(MeasurementType::Instantaneous, VIFRange::ExternalTemperature, 0, 0, &key, &t->dv_entries)) - { - extractDVdouble(&t->dv_entries, key, &offset, ¤t_temperature_c_); - t->addMoreExplanation(offset, " current temperature (%f C)", current_temperature_c_); - } - - if (findKey(MeasurementType::Instantaneous, VIFRange::ExternalTemperature, 1, 0, &key, &t->dv_entries)) - { - extractDVdouble(&t->dv_entries, key, &offset, &average_temperature_1h_c_); - t->addMoreExplanation(offset, " average temperature 1h (%f C))", average_temperature_1h_c_); - } - -} diff --git a/src/meter_detection.h b/src/meter_detection.h index cd0c8b2..e9db7d4 100644 --- a/src/meter_detection.h +++ b/src/meter_detection.h @@ -31,7 +31,6 @@ X(APATOR162, MANUFACTURER_APA, 0x07, 0x05) \ X(BFW240RADIO, MANUFACTURER_BFW,0x08, 0x02) \ X(CCx01, MANUFACTURER_GSS, 0x02, 0x01) \ - X(CMA12W, MANUFACTURER_ELV, 0x1b, 0x20) \ X(COMPACT5, MANUFACTURER_TCH, 0x04, 0x45) \ X(COMPACT5, MANUFACTURER_TCH, 0xc3, 0x45) \ X(COMPACT5, MANUFACTURER_TCH, 0x43, 0x22) \ diff --git a/src/meters.h b/src/meters.h index 6ca2a74..6ff4c36 100644 --- a/src/meters.h +++ b/src/meters.h @@ -62,7 +62,6 @@ LIST_OF_METER_TYPES X(unknown, 0, UnknownMeter, UNKNOWN, Unknown) \ X(apator162, C1_bit|T1_bit, WaterMeter, APATOR162, Apator162) \ X(bfw240radio,T1_bit, HeatCostAllocationMeter, BFW240RADIO, BFW240Radio) \ - X(cma12w, C1_bit|T1_bit, TempHygroMeter, CMA12W, CMa12w) \ X(compact5, T1_bit, HeatMeter, COMPACT5, Compact5) \ X(dme_07, T1_bit, WaterMeter, DME_07, DME_07) \ X(ebzwmbe, T1_bit, ElectricityMeter, EBZWMBE, EBZWMBE) \