/* Copyright (C) 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("pollucomf"); di.setDefaultFields("name,id,status,total_kwh,total_m3,target_kwh,target_m3,timestamp"); di.setMeterType(MeterType::HeatMeter); di.addLinkMode(LinkMode::T1); // default di.addLinkMode(LinkMode::C1); di.addLinkMode(LinkMode::MBUS); // optional hw module di.addDetection(MANUFACTURER_SEN, 0x04, 0x1d); di.setConstructor([](MeterInfo& mi, DriverInfo& di){ return shared_ptr(new Driver(mi, di)); }); }); Driver::Driver(MeterInfo &mi, DriverInfo &di) : MeterCommonImplementation(mi, di) { addStringField( "status", "Meter status.", DEFAULT_PRINT_PROPERTIES | PrintProperty::STATUS | PrintProperty::INCLUDE_TPL_STATUS); addNumericFieldWithExtractor( "total", "The total energy consumption recorded by this meter.", DEFAULT_PRINT_PROPERTIES, Quantity::Energy, VifScaling::Auto, DifSignedness::Signed, FieldMatcher::build() .set(MeasurementType::Instantaneous) .set(VIFRange::AnyEnergyVIF) ); addNumericFieldWithExtractor( "total", "The total amount of water that has passed through this meter.", DEFAULT_PRINT_PROPERTIES, Quantity::Volume, VifScaling::Auto, DifSignedness::Signed, FieldMatcher::build() .set(MeasurementType::Instantaneous) .set(VIFRange::Volume) ); addNumericFieldWithExtractor( "power", "The active power consumption.", DEFAULT_PRINT_PROPERTIES, Quantity::Power, VifScaling::Auto, DifSignedness::Signed, FieldMatcher::build() .set(MeasurementType::Instantaneous) .set(VIFRange::AnyPowerVIF) ); addNumericFieldWithExtractor( "flow", "The flow of water.", DEFAULT_PRINT_PROPERTIES, Quantity::Flow, VifScaling::Auto, DifSignedness::Signed, FieldMatcher::build() .set(MeasurementType::Instantaneous) .set(VIFRange::VolumeFlow) ); addNumericFieldWithExtractor( "forward", "The forward temperature of the water.", DEFAULT_PRINT_PROPERTIES, Quantity::Temperature, VifScaling::Auto, DifSignedness::Signed, FieldMatcher::build() .set(MeasurementType::Instantaneous) .set(VIFRange::FlowTemperature) ); addNumericFieldWithExtractor( "return", "The return temperature of the water.", DEFAULT_PRINT_PROPERTIES, Quantity::Temperature, VifScaling::Auto, DifSignedness::Signed, FieldMatcher::build() .set(MeasurementType::Instantaneous) .set(VIFRange::ReturnTemperature) ); addStringFieldWithExtractor( "target_date", "The most recent billing period date.", DEFAULT_PRINT_PROPERTIES, FieldMatcher::build() .set(MeasurementType::Instantaneous) .set(VIFRange::Date) .set(StorageNr(1)) ); addNumericFieldWithExtractor( "target", "The energy consumption recorded by this meter at the set date.", DEFAULT_PRINT_PROPERTIES, Quantity::Energy, VifScaling::Auto, DifSignedness::Signed, FieldMatcher::build() .set(MeasurementType::Instantaneous) .set(VIFRange::AnyEnergyVIF) .set(StorageNr(1)) ); addNumericFieldWithExtractor( "target", "The amount of water that had passed through this meter at the set date.", DEFAULT_PRINT_PROPERTIES, Quantity::Volume, VifScaling::Auto, DifSignedness::Signed, FieldMatcher::build() .set(MeasurementType::Instantaneous) .set(VIFRange::Volume) .set(StorageNr(1)) ); addNumericFieldWithExtractor( "forward_max", "The maximum forward temperature of the water.", DEFAULT_PRINT_PROPERTIES, Quantity::Temperature, VifScaling::Auto, DifSignedness::Signed, FieldMatcher::build() .set(MeasurementType::Maximum) .set(VIFRange::FlowTemperature) .set(StorageNr(1)) ); addNumericFieldWithExtractor( "return_max", "The maximum return temperature of the water.", DEFAULT_PRINT_PROPERTIES, Quantity::Temperature, VifScaling::Auto, DifSignedness::Signed, FieldMatcher::build() .set(MeasurementType::Maximum) .set(VIFRange::ReturnTemperature) .set(StorageNr(1)) ); addNumericFieldWithExtractor( "flow_max", "The maximum forward flow of water through this meter.", DEFAULT_PRINT_PROPERTIES, Quantity::Flow, VifScaling::Auto, DifSignedness::Signed, FieldMatcher::build() .set(MeasurementType::Maximum) .set(VIFRange::VolumeFlow) .set(StorageNr(1)) ); addOptionalLibraryFields("operating_time_h,on_time_h,on_time_at_error_h,meter_datetime"); } } // Test: Heat pollucomf 14175439 NOKEY // Comment: // telegram=|5e44ae4c395417141d047a9f0050252f2f046d2d32d92c0223B701040600000000041331000000032B000000033B000000025a3201025ef2003222000002fd170000426cBf2c440600000000441301000000525a0000525e0000533B000000| // {"media":"heat","meter":"pollucomf","name":"Heat","id":"14175439","status":"OK","total_kwh":0,"total_m3":0.049,"power_kw":0,"flow_m3h":0,"forward_c":30.6,"return_c":24.2,"target_date":"2021-12-31","target_kwh":0,"target_m3":0.001,"forward_max_c":0,"return_max_c":0,"flow_max_m3h":0,"on_time_h":10536,"on_time_at_error_h":0,"meter_datetime":"2022-12-25 18:45","timestamp":"1111-11-11T11:11:11Z"} // |Heat;14175439;OK;0;0.049;0;0.001;1111-11-11 11:11.11