From fadce1cb60c094144cb90edd73a351a6b6e0326d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20=C3=96hrstr=C3=B6m?= Date: Fri, 11 Nov 2022 12:24:00 +0100 Subject: [PATCH] Refactor esyswm to new driver format. --- Makefile | 8 + simulations/simulation_t1.txt | 8 +- src/driver_esyswm.cc | 160 ++++++++++++++++++ src/dvparser.h | 1 + src/meter_detection.h | 1 - src/meter_esyswm.cc | 300 ---------------------------------- src/meters.cc | 20 +++ src/meters.h | 1 - tests/test_listen_to_all.sh | 2 +- 9 files changed, 194 insertions(+), 307 deletions(-) create mode 100644 src/driver_esyswm.cc delete mode 100644 src/meter_esyswm.cc diff --git a/Makefile b/Makefile index c4a1933..abe4676 100644 --- a/Makefile +++ b/Makefile @@ -258,6 +258,14 @@ $(BUILD)/testinternals: $(BUILD)/testinternals.o $(BUILD)/fuzz: $(PROG_OBJS) $(DRIVER_OBJS) $(BUILD)/fuzz.o $(CXX) -o $(BUILD)/fuzz $(PROG_OBJS) $(DRIVER_OBJS) $(BUILD)/fuzz.o $(LDFLAGS) -lrtlsdr -lpthread +clean_executables: + rm -rf build/wmbusmeters* build_arm/wmbusmeters* build_debug/wmbusmeters* build_arm_debug/wmbusmeters* *~ + rm -rf build/testinternal* build_arm/testinternal* build_debug/testinternal* build_arm_debug/testinternal* + $(RM) testaes/test_input.txt testaes/test_stderr.txt + $(RM) testoutput/test_expected.txt testoutput/test_input.txt \ + testoutput/test_response.txt testoutput/test_responses.txt \ + testoutput/test_stderr.txt + clean: rm -rf build/* build_arm/* build_debug/* build_arm_debug/* *~ $(RM) testaes/test_input.txt testaes/test_stderr.txt diff --git a/simulations/simulation_t1.txt b/simulations/simulation_t1.txt index f89e234..d6dc789 100644 --- a/simulations/simulation_t1.txt +++ b/simulations/simulation_t1.txt @@ -164,13 +164,13 @@ telegram=|5B445A149922992202378C20F6900F002C25BC9E0000BF48954821BC508D7299229922 # static telegram telegram=|7B4479169977997730378C208B900F002C25E4EF0A002EA98E7D58B3ADC57299779977991611028B005087102F2F#0DFD090F34302e3030562030303030303030300D790E31323334353637383839595345310DFD100AAAAAAAAAAAAAAAAAAAAA0D780E31323334353637383930594553312F2F2F2F2F2F2F2F2F2F2F| -{"media":"electricity","meter":"esyswm","name":"Elen2","id":"77997799","total_energy_consumption_kwh":0,"current_power_consumption_kw":0,"total_energy_production_kwh":0,"total_energy_consumption_tariff1_kwh":0,"total_energy_consumption_tariff2_kwh":0,"current_power_consumption_phase1_kw":0,"current_power_consumption_phase2_kw":0,"current_power_consumption_phase3_kw":0,"enhanced_id":"1ESY9887654321","version":"00000000 V00.04","location_hex":"AAAAAAAAAAAAAAAAAAAA","fabrication_no":"1SEY0987654321","timestamp":"1111-11-11T11:11:11Z"} -|Elen2;77997799;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;1ESY9887654321;1111-11-11 11:11.11 +{"media":"electricity","meter":"esyswm","name":"Elen2","id":"77997799","fabrication_no":"1SEY0987654321","enhanced_id":"1ESY9887654321","location":"AAAAAAAAAAAAAAAAAAAA","location_hex":"AAAAAAAAAAAAAAAAAAAA","total_energy_consumption_kwh":null,"current_power_consumption_kw":null,"total_energy_production_kwh":null,"total_energy_consumption_tariff1_kwh":null,"total_energy_consumption_tariff2_kwh":null,"current_power_consumption_phase1_kw":null,"current_power_consumption_phase2_kw":null,"current_power_consumption_phase3_kw":null,"version":"00000000 V00.04","timestamp":"1111-11-11T11:11:11Z"} +|Elen2;77997799;null;null;null;null;null;null;null;null;1ESY9887654321;1111-11-11 11:11.11 # dynamic telegram telegram=|7B4479169977997730378C20F0900F002C2549EE0A0077C19D3D1A08ABCD729977997779161102F0005007102F2F#0702F5C3FA000000000007823C5407000000000000841004E081020084200415000000042938AB000004A9FF01FA0A000004A9FF02050A000004A9FF03389600002F2F2F2F2F2F2F2F2F2F2F2F2F| -{"media":"electricity","meter":"esyswm","name":"Elen2","id":"77997799","total_energy_consumption_kwh":1643.4165,"current_power_consumption_kw":0.43832,"total_energy_production_kwh":0.1876,"total_energy_consumption_tariff1_kwh":1643.2,"total_energy_consumption_tariff2_kwh":0.21,"current_power_consumption_phase1_kw":0.0281,"current_power_consumption_phase2_kw":0.02565,"current_power_consumption_phase3_kw":0.38456,"enhanced_id":"1ESY9887654321","version":"00000000 V00.04","location_hex":"AAAAAAAAAAAAAAAAAAAA","fabrication_no":"1SEY0987654321","timestamp":"1111-11-11T11:11:11Z"} -|Elen2;77997799;1643.416500;0.438320;0.187600;1643.200000;0.210000;0.028100;0.025650;0.384560;1ESY9887654321;1111-11-11 11:11.11 +{"media":"electricity","meter":"esyswm","name":"Elen2","id":"77997799","fabrication_no":"1SEY0987654321","enhanced_id":"1ESY9887654321","location":"AAAAAAAAAAAAAAAAAAAA","location_hex":"AAAAAAAAAAAAAAAAAAAA","total_energy_consumption_kwh":1643.4165,"current_power_consumption_kw":0.43832,"total_energy_production_kwh":0.1876,"total_energy_consumption_tariff1_kwh":1643.2,"total_energy_consumption_tariff2_kwh":0.21,"current_power_consumption_phase1_kw":0.0281,"current_power_consumption_phase2_kw":0.02565,"current_power_consumption_phase3_kw":0.38456,"version":"00000000 V00.04","timestamp":"1111-11-11T11:11:11Z"} +|Elen2;77997799;1643.4165;0.43832;0.1876;1643.2;0.21;0.0281;0.02565;0.38456;1ESY9887654321;1111-11-11 11:11.11 # Test electricity meter eHZ-P diff --git a/src/driver_esyswm.cc b/src/driver_esyswm.cc new file mode 100644 index 0000000..c13c119 --- /dev/null +++ b/src/driver_esyswm.cc @@ -0,0 +1,160 @@ +/* + 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("esyswm"); + di.setDefaultFields("name,id,total_energy_consumption_kwh,current_power_consumption_kw,total_energy_production_kwh,total_energy_consumption_tariff1_kwh,total_energy_consumption_tariff2_kwh,current_power_consumption_phase1_kw,current_power_consumption_phase2_kw,current_power_consumption_phase3_kw,enhanced_id,timestamp"); + di.setMeterType(MeterType::ElectricityMeter); + di.addLinkMode(LinkMode::T1); + di.addDetection(MANUFACTURER_ESY, 0x37, 0x30); // Wireless adapter for electricity meter. + di.addDetection(MANUFACTURER_ESY, 0x02, 0x11); + di.setConstructor([](MeterInfo& mi, DriverInfo& di){ return shared_ptr(new Driver(mi, di)); }); + }); + + Driver::Driver(MeterInfo &mi, DriverInfo &di) : MeterCommonImplementation(mi, di) + { + addOptionalCommonFields(); + + addStringFieldWithExtractor( + "location_hex", + "Meter installed at this customer location. Deprecate field.", + PrintProperty::JSON | PrintProperty::OPTIONAL | PrintProperty::DEPRECATED, + FieldMatcher::build() + .set(MeasurementType::Instantaneous) + .set(VIFRange::Location) + ); + + addNumericFieldWithExtractor( + "total_energy_consumption", + "The total energy consumption recorded by this meter.", + PrintProperty::JSON | PrintProperty::FIELD | PrintProperty::IMPORTANT, + Quantity::Energy, + VifScaling::Auto, + FieldMatcher::build() + .set(MeasurementType::Instantaneous) + .set(VIFRange::EnergyWh) + ); + + addNumericFieldWithExtractor( + "current_power_consumption", + "Calculated sum of power consumption of all phases.", + PrintProperty::JSON | PrintProperty::FIELD, + Quantity::Power, + VifScaling::Auto, + FieldMatcher::build() + .set(MeasurementType::Instantaneous) + .set(VIFRange::AnyPowerVIF) + ); + + addNumericFieldWithExtractor( + "total_energy_production", + "The total energy production recorded by this meter.", + PrintProperty::JSON | PrintProperty::FIELD | PrintProperty::IMPORTANT, + Quantity::Energy, + VifScaling::Auto, + FieldMatcher::build() + .set(MeasurementType::Instantaneous) + .set(VIFRange::EnergyWh) + .add(VIFCombinable::BackwardFlow) + ); + + addNumericFieldWithExtractor( + "total_energy_consumption_tariff1", + "The total energy consumption recorded by this meter on tariff 1.", + PrintProperty::JSON | PrintProperty::FIELD | PrintProperty::IMPORTANT, + Quantity::Energy, + VifScaling::Auto, + FieldMatcher::build() + .set(MeasurementType::Instantaneous) + .set(VIFRange::EnergyWh) + .set(TariffNr(1)) + ); + + addNumericFieldWithExtractor( + "total_energy_consumption_tariff2", + "The total energy consumption recorded by this meter on tariff 2.", + PrintProperty::JSON | PrintProperty::FIELD | PrintProperty::IMPORTANT, + Quantity::Energy, + VifScaling::Auto, + FieldMatcher::build() + .set(MeasurementType::Instantaneous) + .set(VIFRange::EnergyWh) + .set(TariffNr(2)) + ); + + addNumericFieldWithExtractor( + "current_power_consumption_phase1", + "Current power consumption phase 1.", + PrintProperty::JSON | PrintProperty::FIELD, + Quantity::Power, + VifScaling::Auto, + FieldMatcher::build() + .set(DifVifKey("04A9FF01")) + ); + + addNumericFieldWithExtractor( + "current_power_consumption_phase2", + "Current power consumption phase 2.", + PrintProperty::JSON | PrintProperty::FIELD, + Quantity::Power, + VifScaling::Auto, + FieldMatcher::build() + .set(DifVifKey("04A9FF02")) + ); + + addNumericFieldWithExtractor( + "current_power_consumption_phase3", + "Current power consumption phase 3.", + PrintProperty::JSON | PrintProperty::FIELD, + Quantity::Power, + VifScaling::Auto, + FieldMatcher::build() + .set(DifVifKey("04A9FF03")) + ); + + addStringFieldWithExtractor( + "version", + "Static version information.", + PrintProperty::JSON, + FieldMatcher::build() + .set(MeasurementType::Instantaneous) + .set(DifVifKey("0DFD09")) + ); + + } +} + +// Test: Elen2 esyswm 77997799 NOKEY +// Comment: Static telegram +// telegram=|7B4479169977997730378C208B900F002C25E4EF0A002EA98E7D58B3ADC57299779977991611028B005087102F2F#0DFD090F34302e3030562030303030303030300D790E31323334353637383839595345310DFD100AAAAAAAAAAAAAAAAAAAAA0D780E31323334353637383930594553312F2F2F2F2F2F2F2F2F2F2F| +// {"media":"electricity","meter":"esyswm","name":"Elen2","id":"77997799","fabrication_no":"1SEY0987654321","enhanced_id":"1ESY9887654321","location":"AAAAAAAAAAAAAAAAAAAA","location_hex":"AAAAAAAAAAAAAAAAAAAA","total_energy_consumption_kwh":null,"current_power_consumption_kw":null,"total_energy_production_kwh":null,"total_energy_consumption_tariff1_kwh":null,"total_energy_consumption_tariff2_kwh":null,"current_power_consumption_phase1_kw":null,"current_power_consumption_phase2_kw":null,"current_power_consumption_phase3_kw":null,"version":"00000000 V00.04","timestamp":"1111-11-11T11:11:11Z"} +// |Elen2;77997799;null;null;null;null;null;null;null;null;1ESY9887654321;1111-11-11 11:11.11 + +// Comment: Dynamic telegram +// telegram=|7B4479169977997730378C20F0900F002C2549EE0A0077C19D3D1A08ABCD729977997779161102F0005007102F2F#0702F5C3FA000000000007823C5407000000000000841004E081020084200415000000042938AB000004A9FF01FA0A000004A9FF02050A000004A9FF03389600002F2F2F2F2F2F2F2F2F2F2F2F2F| +// {"media":"electricity","meter":"esyswm","name":"Elen2","id":"77997799","fabrication_no":"1SEY0987654321","enhanced_id":"1ESY9887654321","location":"AAAAAAAAAAAAAAAAAAAA","location_hex":"AAAAAAAAAAAAAAAAAAAA","total_energy_consumption_kwh":1643.4165,"current_power_consumption_kw":0.43832,"total_energy_production_kwh":0.1876,"total_energy_consumption_tariff1_kwh":1643.2,"total_energy_consumption_tariff2_kwh":0.21,"current_power_consumption_phase1_kw":0.0281,"current_power_consumption_phase2_kw":0.02565,"current_power_consumption_phase3_kw":0.38456,"version":"00000000 V00.04","timestamp":"1111-11-11T11:11:11Z"} +// |Elen2;77997799;1643.4165;0.43832;0.1876;1643.2;0.21;0.0281;0.02565;0.38456;1ESY9887654321;1111-11-11 11:11.11 diff --git a/src/dvparser.h b/src/dvparser.h index 16a3f4c..6a25078 100644 --- a/src/dvparser.h +++ b/src/dvparser.h @@ -52,6 +52,7 @@ X(ParameterSet,0x7D0B,0x7D0B, Quantity::Text, Unit::TXT) \ X(ModelVersion,0x7D0C,0x7D0C, Quantity::Text, Unit::TXT) \ X(SoftwareVersion,0x7D0F,0x7D0F, Quantity::Text, Unit::TXT) \ + X(Location,0x7D10,0x7D10, Quantity::Text, Unit::TXT) \ X(Customer,0x7D11,0x7D11, Quantity::Text, Unit::TXT) \ X(ErrorFlags,0x7D17,0x7D17, Quantity::Text, Unit::TXT) \ X(DigitalInput,0x7D1B,0x7D1B, Quantity::Text, Unit::TXT) \ diff --git a/src/meter_detection.h b/src/meter_detection.h index f13fa9f..082cc8f 100644 --- a/src/meter_detection.h +++ b/src/meter_detection.h @@ -29,7 +29,6 @@ #define METER_DETECTION \ X(CCx01, MANUFACTURER_GSS, 0x02, 0x01) \ X(EURISII, MANUFACTURER_INE, 0x08, 0x55) \ - X(ESYSWM, MANUFACTURER_ESY, 0x37, 0x30) \ X(EVO868, MANUFACTURER_MAD, 0x07, 0x50) \ X(FHKVDATAIII,MANUFACTURER_TCH, 0x80, 0x69) \ X(FHKVDATAIII,MANUFACTURER_TCH, 0x80, 0x94) \ diff --git a/src/meter_esyswm.cc b/src/meter_esyswm.cc deleted file mode 100644 index f18af74..0000000 --- a/src/meter_esyswm.cc +++ /dev/null @@ -1,300 +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" -#include"util.h" - -#include - -struct MeterESYSWM : public virtual MeterCommonImplementation -{ - MeterESYSWM(MeterInfo &mi); - - double totalEnergyConsumption(Unit u); - double totalEnergyConsumptionTariff1(Unit u); - double totalEnergyConsumptionTariff2(Unit u); - double currentPowerConsumption(Unit u); - double currentPowerConsumptionPhase1(Unit u); - double currentPowerConsumptionPhase2(Unit u); - double currentPowerConsumptionPhase3(Unit u); - double totalEnergyProduction(Unit u); - double currentPowerProduction(Unit u); - -private: - - void processContent(Telegram *t); - - double total_energy_kwh_ {}; - double total_energy_tariff1_kwh_ {}; - double total_energy_tariff2_kwh_ {}; - double current_power_kw_ {}; - double current_power_phase1_kw_ {}; - double current_power_phase2_kw_ {}; - double current_power_phase3_kw_ {}; - double total_energy_returned_kwh_ {}; - double current_power_returned_kw_ {}; - string device_date_time_; - - // Information sent more rarely and is static. - - string version_; - string enhanced_id_; - string location_hex_; - string fabrication_no_; -}; - -MeterESYSWM::MeterESYSWM(MeterInfo &mi) : - MeterCommonImplementation(mi, "esyswm") -{ - setMeterType(MeterType::ElectricityMeter); - setExpectedTPLSecurityMode(TPLSecurityMode::AES_CBC_NO_IV); - - // The ESYS-WM-20 and ESYS-WM15 are addons to the electricity meters. - // media 0x37 Radio converter (meter side) - - addLinkMode(LinkMode::T1); - - addPrint("total_energy_consumption", Quantity::Energy, - [&](Unit u){ return totalEnergyConsumption(u); }, - "The total energy consumption recorded by this meter.", - PrintProperty::FIELD | PrintProperty::JSON); - - addPrint("current_power_consumption", Quantity::Power, - [&](Unit u){ return currentPowerConsumption(u); }, - "Current power consumption.", - PrintProperty::FIELD | PrintProperty::JSON); - - addPrint("total_energy_production", Quantity::Energy, - [&](Unit u){ return totalEnergyProduction(u); }, - "The total energy production recorded by this meter.", - PrintProperty::FIELD | PrintProperty::JSON); - - addPrint("total_energy_consumption_tariff1", Quantity::Energy, - [&](Unit u){ return totalEnergyConsumptionTariff1(u); }, - "The total energy consumption recorded by this meter on tariff 1.", - PrintProperty::FIELD | PrintProperty::JSON); - - addPrint("total_energy_consumption_tariff2", Quantity::Energy, - [&](Unit u){ return totalEnergyConsumptionTariff2(u); }, - "The total energy consumption recorded by this meter on tariff 2.", - PrintProperty::FIELD | PrintProperty::JSON); - - addPrint("current_power_consumption_phase1", Quantity::Power, - [&](Unit u){ return currentPowerConsumptionPhase1(u); }, - "Current power consumption phase 1.", - PrintProperty::FIELD | PrintProperty::JSON); - - addPrint("current_power_consumption_phase2", Quantity::Power, - [&](Unit u){ return currentPowerConsumptionPhase2(u); }, - "Current power consumption phase 2.", - PrintProperty::FIELD | PrintProperty::JSON); - - addPrint("current_power_consumption_phase3", Quantity::Power, - [&](Unit u){ return currentPowerConsumptionPhase3(u); }, - "Current power consumption phase 3.", - PrintProperty::FIELD | PrintProperty::JSON); - - addPrint("enhanced_id", Quantity::Text, - [&](){ return enhanced_id_; }, - "Static enhanced id information.", - PrintProperty::FIELD | PrintProperty::JSON); - - addPrint("version", Quantity::Text, - [&](){ return version_; }, - "Static version information.", - PrintProperty::JSON); - - addPrint("location_hex", Quantity::Text, - [&](){ return location_hex_; }, - "Static location information.", - PrintProperty::JSON); - - addPrint("fabrication_no", Quantity::Text, - [&](){ return fabrication_no_; }, - "Static fabrication no information.", - PrintProperty::JSON); -} - -shared_ptr createESYSWM(MeterInfo &mi) -{ - return shared_ptr(new MeterESYSWM(mi)); -} - -double MeterESYSWM::totalEnergyConsumption(Unit u) -{ - assertQuantity(u, Quantity::Energy); - return convert(total_energy_kwh_, Unit::KWH, u); -} - -double MeterESYSWM::totalEnergyConsumptionTariff1(Unit u) -{ - assertQuantity(u, Quantity::Energy); - return convert(total_energy_tariff1_kwh_, Unit::KWH, u); -} - -double MeterESYSWM::totalEnergyConsumptionTariff2(Unit u) -{ - assertQuantity(u, Quantity::Energy); - return convert(total_energy_tariff2_kwh_, Unit::KWH, u); -} - -double MeterESYSWM::currentPowerConsumption(Unit u) -{ - assertQuantity(u, Quantity::Power); - return convert(current_power_kw_, Unit::KW, u); -} - -double MeterESYSWM::currentPowerConsumptionPhase1(Unit u) -{ - assertQuantity(u, Quantity::Power); - return convert(current_power_phase1_kw_, Unit::KW, u); -} - -double MeterESYSWM::currentPowerConsumptionPhase2(Unit u) -{ - assertQuantity(u, Quantity::Power); - return convert(current_power_phase2_kw_, Unit::KW, u); -} - -double MeterESYSWM::currentPowerConsumptionPhase3(Unit u) -{ - assertQuantity(u, Quantity::Power); - return convert(current_power_phase3_kw_, Unit::KW, u); -} - -double MeterESYSWM::totalEnergyProduction(Unit u) -{ - assertQuantity(u, Quantity::Energy); - return convert(total_energy_returned_kwh_, Unit::KWH, u); -} - -double MeterESYSWM::currentPowerProduction(Unit u) -{ - assertQuantity(u, Quantity::Power); - return convert(current_power_returned_kw_, Unit::KW, u); -} - -void MeterESYSWM::processContent(Telegram *t) -{ - /* - (esyswm) 2e: 07 dif (64 Bit Integer/Binary Instantaneous value) - (esyswm) 2f: 02 vif (Energy 10⁻¹ Wh) - (esyswm) 30: * F5C3FA0000000000 total energy (1643.416500 kwh) - (esyswm) 38: 07 dif (64 Bit Integer/Binary Instantaneous value) - (esyswm) 39: 82 vif (Energy 10⁻¹ Wh) - (esyswm) 3a: 3C vife (backward flow) - (esyswm) 3b: * 5407000000000000 total energy returned (0.187600 kwh) - (esyswm) 43: 84 dif (32 Bit Integer/Binary Instantaneous value) - (esyswm) 44: 10 dife (subunit=0 tariff=1 storagenr=0) - (esyswm) 45: 04 vif (Energy 10¹ Wh) - (esyswm) 46: * E0810200 total energy tariff 1 (1643.200000 kwh) - (esyswm) 4a: 84 dif (32 Bit Integer/Binary Instantaneous value) - (esyswm) 4b: 20 dife (subunit=0 tariff=2 storagenr=0) - (esyswm) 4c: 04 vif (Energy 10¹ Wh) - (esyswm) 4d: * 15000000 total energy tariff 2 (0.210000 kwh) - (esyswm) 51: 04 dif (32 Bit Integer/Binary Instantaneous value) - (esyswm) 52: 29 vif (Power 10⁻² W) - (esyswm) 53: * 38AB0000 current power (0.438320 kw) - (esyswm) 57: 04 dif (32 Bit Integer/Binary Instantaneous value) - (esyswm) 58: A9 vif (Power 10⁻² W) - (esyswm) 59: FF vife (additive correction constant: unit of VIF * 10^0) - (esyswm) 5a: 01 vife (?) - (esyswm) 5b: * FA0A0000 current power phase 1 (0.028100 kwh) - (esyswm) 5f: 04 dif (32 Bit Integer/Binary Instantaneous value) - (esyswm) 60: A9 vif (Power 10⁻² W) - (esyswm) 61: FF vife (additive correction constant: unit of VIF * 10^0) - (esyswm) 62: 02 vife (?) - (esyswm) 63: * 050A0000 current power phase 2 (0.000000 kwh) - (esyswm) 67: 04 dif (32 Bit Integer/Binary Instantaneous value) - (esyswm) 68: A9 vif (Power 10⁻² W) - (esyswm) 69: FF vife (additive correction constant: unit of VIF * 10^0) - (esyswm) 6a: 03 vife (?) - (esyswm) 6b: * 38960000 current power phase 3 (0.000000 kwh) - */ - - /* - (esyswm) 2e: 0D dif (variable length Instantaneous value) - (esyswm) 2f: FD vif (Second extension of VIF-codes) - (esyswm) 30: 09 vife (Medium (as in fixed header)) - (esyswm) 31: 0F varlen=15 - (esyswm) 32: - (esyswm) 41: 0D dif (variable length Instantaneous value) - (esyswm) 42: 79 vif (Enhanced identification) - (esyswm) 43: 0E varlen=14 - (esyswm) 44: - (esyswm) 52: 0D dif (variable length Instantaneous value) - (esyswm) 53: FD vif (Second extension of VIF-codes) - (esyswm) 54: 10 vife (Customer location) - (esyswm) 55: 0A varlen=10 - (esyswm) 56: - (esyswm) 60: 0D dif (variable length Instantaneous value) - (esyswm) 61: 78 vif (Fabrication no) - (esyswm) 62: 0E varlen=14 - (esyswm) 63: - */ - - int offset; - string key; - - if (findKey(MeasurementType::Instantaneous, VIFRange::EnergyWh, 0, 0, &key, &t->dv_entries)) { - extractDVdouble(&t->dv_entries, key, &offset, &total_energy_kwh_); - t->addMoreExplanation(offset, " total energy (%f kwh)", total_energy_kwh_); - } - - if (findKey(MeasurementType::Instantaneous, VIFRange::EnergyWh, 0, 1, &key, &t->dv_entries)) { - extractDVdouble(&t->dv_entries, key, &offset, &total_energy_tariff1_kwh_); - t->addMoreExplanation(offset, " total energy tariff 1 (%f kwh)", total_energy_tariff1_kwh_); - } - - if (findKey(MeasurementType::Instantaneous, VIFRange::EnergyWh, 0, 2, &key, &t->dv_entries)) { - extractDVdouble(&t->dv_entries, key, &offset, &total_energy_tariff2_kwh_); - t->addMoreExplanation(offset, " total energy tariff 2 (%f kwh)", total_energy_tariff2_kwh_); - } - - if (findKey(MeasurementType::Instantaneous, VIFRange::PowerW, 0, 0, &key, &t->dv_entries)) { - extractDVdouble(&t->dv_entries, key, &offset, ¤t_power_kw_); - t->addMoreExplanation(offset, " current power (%f kw)", current_power_kw_); - } - - extractDVdouble(&t->dv_entries, "07823C", &offset, &total_energy_returned_kwh_); - t->addMoreExplanation(offset, " total energy returned (%f kwh)", total_energy_returned_kwh_); - - extractDVdouble(&t->dv_entries, "04A9FF01", &offset, ¤t_power_phase1_kw_); - t->addMoreExplanation(offset, " current power phase 1 (%f kwh)", current_power_phase1_kw_); - - extractDVdouble(&t->dv_entries, "04A9FF02", &offset, ¤t_power_phase2_kw_); - t->addMoreExplanation(offset, " current power phase 2 (%f kwh)", current_power_phase2_kw_); - - extractDVdouble(&t->dv_entries, "04A9FF03", &offset, ¤t_power_phase3_kw_); - t->addMoreExplanation(offset, " current power phase 3 (%f kwh)", current_power_phase3_kw_); - - extractDVReadableString(&t->dv_entries, "0DFD09", &offset, &version_); - t->addMoreExplanation(offset, " version (%s)", version_.c_str()); - - extractDVReadableString(&t->dv_entries, "0D79", &offset, &enhanced_id_); - t->addMoreExplanation(offset, " enhanced id (%s)", enhanced_id_.c_str()); - - extractDVHexString(&t->dv_entries, "0DFD10", &offset, &location_hex_); - t->addMoreExplanation(offset, " location (%s)", location_hex_.c_str()); - - extractDVReadableString(&t->dv_entries, "0D78", &offset, &fabrication_no_); - t->addMoreExplanation(offset, " fabrication no (%s)", fabrication_no_.c_str()); -} diff --git a/src/meters.cc b/src/meters.cc index 1602388..e67e293 100644 --- a/src/meters.cc +++ b/src/meters.cc @@ -2931,6 +2931,8 @@ bool FieldInfo::extractString(Meter *m, Telegram *t, DVEntry *dve) matcher_.vif_range == VIFRange::ModelVersion || matcher_.vif_range == VIFRange::SoftwareVersion || matcher_.vif_range == VIFRange::Customer || + matcher_.vif_range == VIFRange::Location || + matcher_.vif_range == VIFRange::Any || matcher_.vif_range == VIFRange::ParameterSet) { string extracted_id; @@ -3057,6 +3059,24 @@ void MeterCommonImplementation::addOptionalCommonFields() .set(VIFRange::SoftwareVersion) ); + addStringFieldWithExtractor( + "customer", + "Customer name.", + PrintProperty::JSON | PrintProperty::OPTIONAL, + FieldMatcher::build() + .set(MeasurementType::Instantaneous) + .set(VIFRange::Customer) + ); + + addStringFieldWithExtractor( + "location", + "Meter installed at this customer location.", + PrintProperty::JSON | PrintProperty::OPTIONAL, + FieldMatcher::build() + .set(MeasurementType::Instantaneous) + .set(VIFRange::Location) + ); + addNumericFieldWithExtractor( "operating_time", "How long the meter has been collecting data.", diff --git a/src/meters.h b/src/meters.h index 483c9a0..5993a6d 100644 --- a/src/meters.h +++ b/src/meters.h @@ -62,7 +62,6 @@ LIST_OF_METER_TYPES X(auto, 0, AutoMeter, AUTO, Auto) \ X(unknown, 0, UnknownMeter, UNKNOWN, Unknown) \ X(eurisii, T1_bit, HeatCostAllocationMeter, EURISII, EurisII) \ - X(esyswm, T1_bit, ElectricityMeter, ESYSWM, ESYSWM) \ X(evo868, T1_bit, WaterMeter, EVO868, EVO868) \ X(fhkvdataiii,T1_bit, HeatCostAllocationMeter, FHKVDATAIII, FHKVDataIII) \ X(fhkvdataiv, T1_bit, HeatCostAllocationMeter, FHKVDATAIV, FHKVDataIV) \ diff --git a/tests/test_listen_to_all.sh b/tests/test_listen_to_all.sh index 0da0f71..3ad532c 100755 --- a/tests/test_listen_to_all.sh +++ b/tests/test_listen_to_all.sh @@ -194,7 +194,7 @@ Received telegram from: 77997799 manufacturer: (ESY) EasyMeter (0x1679) type: Electricity meter (0x02) encrypted ver: 0x11 - driver: esyswm + driver: esyswm esyswm Received telegram from: 55995599 manufacturer: (EMH) EMH metering formerly EMH Elektrizitatszahler (0x15a8) type: Electricity meter (0x02) encrypted