diff --git a/CHANGES b/CHANGES index 044054e..06ad4da 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ + +Janus Bo Andersen fixed the omnipower driver! Thanks Janus! + Version 1.0.4: 2020-12-05 Nikodem added support for Multical803! Thanks Nikodem! diff --git a/README.md b/README.md index 87aa354..df83af4 100644 --- a/README.md +++ b/README.md @@ -316,6 +316,7 @@ eBZ wMB-E01 (ebzwmbe) EMH Metering (ehzp) Tauron Amiplus (amiplus) (includes vendor apator and echelon) Gavazzi EM24 (em24) +Kamstrup Omnipower (omnipower) ``` The wmbus dongles imst871a can listen to one type of wmbus telegrams diff --git a/simulations/simulation_c1.txt b/simulations/simulation_c1.txt index 2c29cf8..4d6810b 100644 --- a/simulations/simulation_c1.txt +++ b/simulations/simulation_c1.txt @@ -56,3 +56,12 @@ telegram=|42442D2C3636363635048D20E18025B62087D078|0406A500000004FF072B01000004F # Test Multical803 C1 telegram telegram=|88442D2C8180808039048D20864051322084C178|040F0000000004FF070000000004FF0800000000041400000000844014000000008480401400000000043B0000000002590000025D0000142D0000000084100F0000000084200F0000000004FF2260000100026C892B440F00000000441400000000C4401400000000C480401400000000426C812B| {"media":"heat","meter":"multical803","name":"Heater","id":"80808081","total_energy_consumption_kwh":0,"total_volume_m3":0,"volume_flow_m3h":0,"t1_temperature_c":0,"t2_temperature_c":0,"at_date":"2020-11-09 00:00","current_status":"SENSOR_T1_BELOW_MEASURING_RANGE SENSOR_T2_BELOW_MEASURING_RANGE","energy_forward_kwh":0,"energy_returned_kwh":0,"timestamp":"1111-11-11T11:11:11Z"} + +# Test Kamstrup OmniPower C1 tlg +# Full tlg +telegram=|2D442D2C5768663230028D20E4E2C81C20878C78|04041A03000004843C00000000042B0300000004AB3C00000000| +{"media":"electricity","meter":"omnipower","name":"myomnipower","id":"32666857","total_energy_consumption_kwh":7.94,"total_energy_production_kwh":0,"current_power_consumption_kw":0.003,"current_power_production_kw":0,"timestamp":"1111-11-11T11:11:11Z"} + +# Compact tlg +telegram=|27442D2C5768663230028D20E900C91C2011BA79138CCCFB|1A030000000000000300000000000000| +{"media":"electricity","meter":"omnipower","name":"myomnipower","id":"32666857","total_energy_consumption_kwh":7.94,"total_energy_production_kwh":0,"current_power_consumption_kw":0.003,"current_power_production_kw":0,"timestamp":"1111-11-11T11:11:11Z"} diff --git a/src/meter_omnipower.cc b/src/meter_omnipower.cc index 24bd03b..ed42634 100644 --- a/src/meter_omnipower.cc +++ b/src/meter_omnipower.cc @@ -15,6 +15,31 @@ along with this program. If not, see . */ +/* +Implemented October 2020 Janus Bo Andersen: +Implements Kamstrup OmniPower, energy meter. +This C1 WM-Bus meter broadcasts: +- Accumulated energy consumption (A+, kWh) +- Accumulated energy production (A-, kWh) +- Current power consumption (P+, kW) +- Current power production (P-, kW) + +According to Kamstrup doc. 58101496_C1_GB_05.2018 +(Wireless M-Bus Module for OMNIPOWER), the single-phase, +three-phase and CT meters send the same datagram. + +Meter version. Implementation tested against meter: +Kamstrup one-phase with firmware version 0x30. + +Encryption: +Meter uses AES-128 in CTR mode, which is the only mode supported by +the extended link layer (wm-bus), see EN 13757-4:2019. +Security mode is set during instatiation as +TPLSecurityMode::AES_CBC_IV, but this is overridden anyway when +reading the 3 ENC bits using the function in the wmbus.cc file. + +*/ + #include"dvparser.h" #include"meters.h" #include"meters_common_implementation.h" @@ -26,12 +51,19 @@ struct MeterOmnipower : public virtual ElectricityMeter, public virtual MeterCom MeterOmnipower(MeterInfo &mi); double totalEnergyConsumption(Unit u); + double totalEnergyBackward(Unit u); + double powerConsumption(Unit u); + double powerBackward(Unit u); private: void processContent(Telegram *t); - double total_energy_kwh_ {}; + double total_energy_kwh_{}; + double total_energy_backward_kwh_{}; + double power_kw_{}; + double power_backward_kw_{}; + }; shared_ptr createOmnipower(MeterInfo &mi) @@ -50,6 +82,21 @@ MeterOmnipower::MeterOmnipower(MeterInfo &mi) : [&](Unit u){ return totalEnergyConsumption(u); }, "The total energy consumption recorded by this meter.", true, true); + + addPrint("total_energy_production", Quantity::Energy, + [&](Unit u){ return totalEnergyBackward(u); }, + "The total energy backward (production) recorded by this meter.", + true, true); + + addPrint("current_power_consumption", Quantity::Power, + [&](Unit u){ return powerConsumption(u); }, + "The current power consumption on this meter.", + true, true); + + addPrint("current_power_production", Quantity::Power, + [&](Unit u){ return powerBackward(u); }, + "The current power backward on this meter.", + true, true); } double MeterOmnipower::totalEnergyConsumption(Unit u) @@ -58,15 +105,60 @@ double MeterOmnipower::totalEnergyConsumption(Unit u) return convert(total_energy_kwh_, Unit::KWH, u); } +double MeterOmnipower::totalEnergyBackward(Unit u) +{ + assertQuantity(u, Quantity::Energy); + return convert(total_energy_backward_kwh_, Unit::KWH, u); +} + +double MeterOmnipower::powerConsumption(Unit u) +{ + assertQuantity(u, Quantity::Power); + return convert(power_kw_, Unit::KW, u); +} + +double MeterOmnipower::powerBackward(Unit u) +{ + assertQuantity(u, Quantity::Power); + return convert(power_backward_kw_, Unit::KW, u); +} + + void MeterOmnipower::processContent(Telegram *t) { - // Meter record: - // 04 dif (32 Bit Integer/Binary Instantaneous value) - // 83 vif (Energy Wh) - // 3b vife (Forward flow contribution only) - // xx xx xx xx (total energy) + // Data Record header established from telegram analysis + // 04 04 (32 bit uint) Energy 10^1 Wh (consumption), A+ + // 04 84 3C (32 bit uint) Energy 10^1 Wh (production), A- + // 04 2B (32 bit uint) Power 10^0 W (consumption), P+ + // 04 AB 3C (32 bit uint) Power 10^0 W (production), P- + /* + (omnipower) 14: 04 dif (32 Bit Integer/Binary Instantaneous value) + (omnipower) 15: 04 vif (Energy 10¹ Wh) + (omnipower) 16: * 1A030000 total energy (7.940000 kwh) + (omnipower) 1a: 04 dif (32 Bit Integer/Binary Instantaneous value) + (omnipower) 1b: 84 vif (Energy 10¹ Wh) + (omnipower) 1c: 3C vife (backward flow) + (omnipower) 1d: * 00000000 total energy backward (0.000000 kwh) + (omnipower) 21: 04 dif (32 Bit Integer/Binary Instantaneous value) + (omnipower) 22: 2B vif (Power W) + (omnipower) 23: * 03000000 current power (0.003000 kw) + (omnipower) 27: 04 dif (32 Bit Integer/Binary Instantaneous value) + (omnipower) 28: AB vif (Power W) + (omnipower) 29: 3C vife (backward flow) + (omnipower) 2a: * 00000000 current power (0.000000 kw) + */ int offset; - extractDVdouble(&t->values, "04833B", &offset, &total_energy_kwh_); - t->addMoreExplanation(offset, " total power (%f kwh)", total_energy_kwh_); + extractDVdouble(&t->values, "0404", &offset, &total_energy_kwh_); + t->addMoreExplanation(offset, " total energy (%f kwh)", total_energy_kwh_); + + extractDVdouble(&t->values, "04843C", &offset, &total_energy_backward_kwh_); + t->addMoreExplanation(offset, " total energy backward (%f kwh)", total_energy_backward_kwh_); + + extractDVdouble(&t->values, "042B", &offset, &power_kw_); + t->addMoreExplanation(offset, " current power (%f kw)", power_kw_); + + extractDVdouble(&t->values, "04AB3C", &offset, &power_backward_kw_); + t->addMoreExplanation(offset, " current power (%f kw)", power_backward_kw_); + } diff --git a/src/meters.h b/src/meters.h index 71b424c..6d6c9d7 100644 --- a/src/meters.h +++ b/src/meters.h @@ -146,7 +146,7 @@ X(MULTICAL403,MANUFACTURER_KAM, 0x0d, 0x34) \ X(MULTICAL603,MANUFACTURER_KAM, 0x04, 0x35) \ X(MULTICAL803,MANUFACTURER_KAM, 0x04, 0x39) \ - X(OMNIPOWER, MANUFACTURER_KAM, 0x02, 0x01) \ + X(OMNIPOWER, MANUFACTURER_KAM, 0x02, 0x30) \ X(RFMAMB, MANUFACTURER_BMT, 0x1b, 0x10) \ X(RFMTX1, MANUFACTURER_BMT, 0x07, 0x05) \ X(Q400, MANUFACTURER_AXI, 0x07, 0x10) \ diff --git a/tests/config1/etc/wmbusmeters.d/myomnipower b/tests/config1/etc/wmbusmeters.d/myomnipower new file mode 100644 index 0000000..5e4f750 --- /dev/null +++ b/tests/config1/etc/wmbusmeters.d/myomnipower @@ -0,0 +1,4 @@ +name=myomnipower +type=omnipower +id=32666857 +key= diff --git a/tests/test_c1_meters.sh b/tests/test_c1_meters.sh index eeeb075..440ebe9 100755 --- a/tests/test_c1_meters.sh +++ b/tests/test_c1_meters.sh @@ -20,6 +20,7 @@ $PROG --format=json simulations/simulation_c1.txt \ My403Cooling multical403 78780102 "" \ Heat multical603 36363636 "" \ Heater multical803 80808081 "" \ + myomnipower omnipower 32666857 "" \ > $TEST/test_output.txt 2> $TEST/test_stderr.txt if [ "$?" = "0" ]