kopia lustrzana https://github.com/weetmuts/wmbusmeters
Print OPTIONAL fields that have previously received a value, even if the field is not part of the current telegram. Merge driver whe5x into qcaloric.
rodzic
94683240ea
commit
79e1395fdc
7
CHANGES
7
CHANGES
|
|
@ -1,3 +1,10 @@
|
|||
|
||||
OPTIONAL fields were only printed in the json, if they appeared in the telegram,
|
||||
even if the field had received a value before. Now a field will be printed
|
||||
in the json whenever there is a value stored in the meter object.
|
||||
I.e. an OPTIONAL field that has never received a value will not be printed.
|
||||
A NON-OPTIONAL field that has never received a value will be printed with the value null.
|
||||
|
||||
Version: 1.9.0 2022-09-04
|
||||
|
||||
ATTENTION! The multical21 and flowiq drivers have been refactored to the new driver style.
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ telegram=|314493441234567835087a740000200b6e2701004b6e450100426c5f2ccb086e790000
|
|||
|
||||
# Test another pair of QCalric C1 telegrams
|
||||
telegram=|49449344939291903408780DFF5F350082180000800007B06EFFFF970000009F2C70020000BE26970000000000010018002E001F002E0023FF210008000500020000002F046D220FA227|
|
||||
{"media":"heat cost allocation","meter":"qcaloric","name":"MyElement2","id":"90919293","status":"OK","current_consumption_hca":null,"set_date":null,"consumption_at_set_date_hca":null,"set_date_1":null,"consumption_at_set_date_1_hca":null,"set_date_17":null,"consumption_at_set_date_17_hca":null,"error_date":null,"device_date_time":"2021-07-02 15:34","timestamp":"1111-11-11T11:11:11Z"}
|
||||
{"media":"heat cost allocation","meter":"qcaloric","name":"MyElement2","id":"90919293","status":"OK","current_consumption_hca":null,"set_date":null,"consumption_at_set_date_hca":null,"set_date_1":null,"consumption_at_set_date_1_hca":null,"device_date_time":"2021-07-02 15:34","timestamp":"1111-11-11T11:11:11Z"}
|
||||
|
||||
telegram=|314493449392919034087a520000200b6e9700004b6e700200426c9f2ccb086e970000c2086cbe26326cffff046d2d16a227|
|
||||
{"media":"heat cost allocation","meter":"qcaloric","name":"MyElement2","id":"90919293","status":"OK","current_consumption_hca":97,"set_date":"2020-12-31","consumption_at_set_date_hca":270,"set_date_1":"2020-12-31","consumption_at_set_date_1_hca":270,"set_date_17":"2021-06-30","consumption_at_set_date_17_hca":97,"error_date":"2127-15-31","device_date_time":"2021-07-02 22:45","timestamp":"1111-11-11T11:11:11Z"}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
# Test a HCA WHE465 Qundis
|
||||
|
||||
telegram=|244465323251839134087a4f0000000b6e0403004b6e660300426c9e29326cffff046d1416b921dd2f|
|
||||
{"media":"heat cost allocation","meter":"whe5x","name":"HCA","id":"91835132","status":"OK","current_consumption_hca":304,"set_date":"2020-09-30","consumption_at_set_date_hca":366,"set_date_1":"2020-09-30","consumption_at_set_date_1_hca":366,"error_date":"2127-15-31","device_date_time":"2021-01-25 22:20","timestamp":"1111-11-11T11:11:11Z"}
|
||||
{"media":"heat cost allocation","meter":"qcaloric","name":"HCA","id":"91835132","status":"OK","current_consumption_hca":304,"set_date":"2020-09-30","consumption_at_set_date_hca":366,"set_date_1":"2020-09-30","consumption_at_set_date_1_hca":366,"error_date":"2127-15-31","device_date_time":"2021-01-25 22:20","timestamp":"1111-11-11T11:11:11Z"}
|
||||
|HCA;91835132;304;2020-09-30;366;1111-11-11 11:11.11
|
||||
|
||||
# Test another HCA from Qundis
|
||||
|
|
|
|||
|
|
@ -288,12 +288,12 @@ namespace
|
|||
|
||||
// Type T1A2 telegram:
|
||||
// telegram=|DA44496A5555445588077A320200002F2F_04140000000084800114000000008280016C2124C480011400000080C280016CFFFF84810114000000808281016CFFFFC481011400000080C281016CFFFF84820114000000808282016CFFFFC482011400000080C282016CFFFF84830114000000808283016CFFFFC483011400000080C283016CFFFF84840114000000808284016CFFFFC484011400000080C284016CFFFF84850114000000808285016CFFFFC485011400000080C285016CFFFF84860114000000808286016CFFFFC486011400000080C286016CFFFF|
|
||||
// {"media":"water","meter":"c5isf","name":"Heat","id":"55445555","total_energy_consumption_kwh":0,"total_volume_m3":0,"status":"ERROR REVERSE_FLOW SUPPLY_SENSOR_INTERRUPTED","prev_1_month":"2017-04-01","prev_2_month":"2127-15-31","prev_3_month":"2127-15-31","prev_4_month":"2127-15-31","prev_5_month":"2127-15-31","prev_6_month":"2127-15-31","prev_7_month":"2127-15-31","prev_8_month":"2127-15-31","prev_9_month":"2127-15-31","prev_10_month":"2127-15-31","prev_11_month":"2127-15-31","prev_12_month":"2127-15-31","prev_13_month":"2127-15-31","prev_14_month":"2127-15-31","prev_1_month_m3":0,"prev_2_month_m3":21474836.48,"prev_3_month_m3":21474836.48,"prev_4_month_m3":21474836.48,"prev_5_month_m3":21474836.48,"prev_6_month_m3":21474836.48,"prev_7_month_m3":21474836.48,"prev_8_month_m3":21474836.48,"prev_9_month_m3":21474836.48,"prev_10_month_m3":21474836.48,"prev_11_month_m3":21474836.48,"prev_12_month_m3":21474836.48,"prev_13_month_m3":21474836.48,"prev_14_month_m3":21474836.48,"timestamp":"1111-11-11T11:11:11Z"}
|
||||
// {"media":"water","meter":"c5isf","name":"Heat","id":"55445555","total_energy_consumption_kwh":0,"total_volume_m3":0,"status":"ERROR REVERSE_FLOW SUPPLY_SENSOR_INTERRUPTED","prev_1_month":"2017-04-01","prev_2_month":"2127-15-31","prev_3_month":"2127-15-31","prev_4_month":"2127-15-31","prev_5_month":"2127-15-31","prev_6_month":"2127-15-31","prev_7_month":"2127-15-31","prev_8_month":"2127-15-31","prev_9_month":"2127-15-31","prev_10_month":"2127-15-31","prev_11_month":"2127-15-31","prev_12_month":"2127-15-31","prev_13_month":"2127-15-31","prev_14_month":"2127-15-31","prev_1_month_m3":0,"prev_2_month_m3":21474836.48,"prev_3_month_m3":21474836.48,"prev_4_month_m3":21474836.48,"prev_5_month_m3":21474836.48,"prev_6_month_m3":21474836.48,"prev_7_month_m3":21474836.48,"prev_8_month_m3":21474836.48,"prev_9_month_m3":21474836.48,"prev_10_month_m3":21474836.48,"prev_11_month_m3":21474836.48,"prev_12_month_m3":21474836.48,"prev_13_month_m3":21474836.48,"prev_14_month_m3":21474836.48,"total_energy_consumption_last_month_kwh":0,"timestamp":"1111-11-11T11:11:11Z"}
|
||||
// |Heat;55445555;0.000000;0.000000;ERROR REVERSE_FLOW SUPPLY_SENSOR_INTERRUPTED;1111-11-11 11:11.11
|
||||
|
||||
// Type T1B telegram:
|
||||
// telegram=|5E44496A5555445588047A0A0050052F2F_04061A0000000413C20800008404060000000082046CC121043BA4000000042D1900000002591216025DE21002FD17000084800106000000008280016CC121948001AE25000000002F2F2F2F2F2F|
|
||||
// {"media":"heat","meter":"c5isf","name":"Heat","id":"55445555","total_energy_consumption_kwh":26,"total_volume_m3":2.242,"status":"OK","prev_1_month":"2022-01-01","prev_1_month_kwh":0,"due_energy_consumption_kwh":0,"due_date":"2022-01-01","volume_flow_m3h":0.164,"power_kw":2.5,"total_energy_consumption_last_month_kwh":0,"max_power_last_month_kw":0,"flow_temperature_c":56.5,"return_temperature_c":43.22,"timestamp":"1111-11-11T11:11:11Z"}
|
||||
// {"media":"heat","meter":"c5isf","name":"Heat","id":"55445555","total_energy_consumption_kwh":26,"total_volume_m3":2.242,"status":"OK","prev_1_month":"2022-01-01","prev_2_month":"2127-15-31","prev_3_month":"2127-15-31","prev_4_month":"2127-15-31","prev_5_month":"2127-15-31","prev_6_month":"2127-15-31","prev_7_month":"2127-15-31","prev_8_month":"2127-15-31","prev_9_month":"2127-15-31","prev_10_month":"2127-15-31","prev_11_month":"2127-15-31","prev_12_month":"2127-15-31","prev_13_month":"2127-15-31","prev_14_month":"2127-15-31","prev_1_month_kwh":0,"prev_2_month_kwh":2147483648,"prev_3_month_kwh":2147483648,"prev_4_month_kwh":2147483648,"prev_5_month_kwh":2147483648,"prev_6_month_kwh":2147483648,"prev_7_month_kwh":2147483648,"prev_8_month_kwh":2147483648,"prev_9_month_kwh":2147483648,"prev_10_month_kwh":2147483648,"prev_11_month_kwh":2147483648,"prev_12_month_kwh":2147483648,"prev_13_month_kwh":2147483648,"prev_14_month_kwh":2147483648,"prev_2_month_m3":21474836.48,"prev_3_month_m3":21474836.48,"prev_4_month_m3":21474836.48,"prev_5_month_m3":21474836.48,"prev_6_month_m3":21474836.48,"prev_7_month_m3":21474836.48,"prev_8_month_m3":21474836.48,"prev_9_month_m3":21474836.48,"prev_10_month_m3":21474836.48,"prev_11_month_m3":21474836.48,"prev_12_month_m3":21474836.48,"prev_13_month_m3":21474836.48,"prev_14_month_m3":21474836.48,"due_energy_consumption_kwh":0,"due_date":"2022-01-01","volume_flow_m3h":0.164,"power_kw":2.5,"total_energy_consumption_last_month_kwh":0,"max_power_last_month_kw":0,"flow_temperature_c":56.5,"return_temperature_c":43.22,"timestamp":"1111-11-11T11:11:11Z"}
|
||||
// |Heat;55445555;26.000000;2.242000;OK;1111-11-11 11:11.11
|
||||
|
||||
// Test: Heat c5isf 32002044 NOKEY
|
||||
|
|
|
|||
|
|
@ -204,5 +204,5 @@ namespace
|
|||
// |Water;13963399;nan;nan;null;null;null;2021-12-01 00:24;1111-11-11 11:11.11
|
||||
|
||||
// telegram=|2D4465329933961318067ADA000000_0C13567100004C1300000000426CFFFF02BB560000326CFFFF046D2307A12C|
|
||||
// {"media":"warm water","meter":"lse_07_17","name":"Water","id":"13963399","total_m3":7.156,"due_date_m3":0,"due_date":"2127-15-31","error_code":"OK","error_date":"2127-15-31","device_date_time":"2021-12-01 07:35","timestamp":"1111-11-11T11:11:11Z"}
|
||||
// {"media":"warm water","meter":"lse_07_17","name":"Water","id":"13963399","total_m3":7.156,"due_date_m3":0,"due_date":"2127-15-31","what_date_m3":7,"what_date":"2021-11-30","error_code":"OK","error_date":"2127-15-31","device_date_time":"2021-12-01 07:35","meter_version":"11","timestamp":"1111-11-11T11:11:11Z"}
|
||||
// |Water;13963399;7.156000;0.000000;2127-15-31;OK;2127-15-31;2021-12-01 07:35;1111-11-11 11:11.11
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ namespace
|
|||
.set(StorageNr(8))
|
||||
);
|
||||
|
||||
/* The wire mbus telegram contains 4 totals and dates. For the moment we only print nr 1 which is the latest. */
|
||||
// The wire mbus telegram contains 4 totals and dates. For the moment we only print nr 1 which is the latest.
|
||||
addNumericFieldWithExtractor(
|
||||
"target",
|
||||
"The total water consumption recorded at the beginning of this month.",
|
||||
|
|
|
|||
|
|
@ -27,10 +27,13 @@ namespace
|
|||
static bool ok = registerDriver([](DriverInfo&di)
|
||||
{
|
||||
di.setName("qcaloric");
|
||||
di.addNameAlias("whe5x");
|
||||
di.setDefaultFields("name,id,current_consumption_hca,set_date,consumption_at_set_date_hca,timestamp");
|
||||
di.setMeterType(MeterType::HeatCostAllocationMeter);
|
||||
di.addLinkMode(LinkMode::C1);
|
||||
di.addLinkMode(LinkMode::T1);
|
||||
di.addLinkMode(LinkMode::S1);
|
||||
di.addDetection(MANUFACTURER_LSE, 0x08, 0x34);
|
||||
di.addDetection(MANUFACTURER_LSE, 0x08, 0x35);
|
||||
di.addDetection(MANUFACTURER_QDS, 0x08, 0x35);
|
||||
di.addDetection(MANUFACTURER_QDS, 0x08, 0x34);
|
||||
|
|
@ -104,7 +107,7 @@ namespace
|
|||
addStringFieldWithExtractor(
|
||||
"set_date_17",
|
||||
"The 17 billing period date.",
|
||||
PrintProperty::JSON | PrintProperty::FIELD,
|
||||
PrintProperty::JSON | PrintProperty::FIELD | PrintProperty::OPTIONAL,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Date)
|
||||
|
|
@ -114,7 +117,7 @@ namespace
|
|||
addNumericFieldWithExtractor(
|
||||
"consumption_at_set_date_17",
|
||||
"Heat cost allocation at the 17 billing period date.",
|
||||
PrintProperty::JSON | PrintProperty::FIELD,
|
||||
PrintProperty::JSON | PrintProperty::FIELD | PrintProperty::OPTIONAL,
|
||||
Quantity::HCA,
|
||||
VifScaling::Auto,
|
||||
FieldMatcher::build()
|
||||
|
|
@ -126,7 +129,7 @@ namespace
|
|||
addStringFieldWithExtractor(
|
||||
"error_date",
|
||||
"Date when the meter entered an error state.",
|
||||
PrintProperty::JSON,
|
||||
PrintProperty::JSON | PrintProperty::OPTIONAL,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::AtError)
|
||||
.set(VIFRange::Date)
|
||||
|
|
@ -153,7 +156,7 @@ namespace
|
|||
// Test: MyElement2 qcaloric 90919293 NOKEY
|
||||
// Comment: Test mostly proprietary telegram without values
|
||||
// telegram=|49449344939291903408780DFF5F350082180000800007B06EFFFF970000009F2C70020000BE26970000000000010018002E001F002E0023FF210008000500020000002F046D220FA227|
|
||||
// {"media":"heat cost allocation","meter":"qcaloric","name":"MyElement2","id":"90919293","status":"OK","current_consumption_hca":null,"set_date":null,"consumption_at_set_date_hca":null,"set_date_1":null,"consumption_at_set_date_1_hca":null,"set_date_17":null,"consumption_at_set_date_17_hca":null,"error_date":null,"device_date_time":"2021-07-02 15:34","timestamp":"1111-11-11T11:11:11Z"}
|
||||
// {"media":"heat cost allocation","meter":"qcaloric","name":"MyElement2","id":"90919293","status":"OK","current_consumption_hca":null,"set_date":null,"consumption_at_set_date_hca":null,"set_date_1":null,"consumption_at_set_date_1_hca":null,"device_date_time":"2021-07-02 15:34","timestamp":"1111-11-11T11:11:11Z"}
|
||||
// |MyElement2;90919293;null;null;null;1111-11-11 11:11.11
|
||||
|
||||
// Comment: Normal telegram that fills in values.
|
||||
|
|
@ -165,3 +168,10 @@ namespace
|
|||
// telegram=|49449344939291903408780DFF5F350082180000800007B06EFFFF970000009F2C70020000BE26970000000000010018002E001F002E0023FF210008000500020000002F046D220FA228|
|
||||
// {"media":"heat cost allocation","meter":"qcaloric","name":"MyElement2","id":"90919293","status":"OK","current_consumption_hca":97,"set_date":"2020-12-31","consumption_at_set_date_hca":270,"set_date_1":"2020-12-31","consumption_at_set_date_1_hca":270,"set_date_17":"2021-06-30","consumption_at_set_date_17_hca":97,"error_date":"2127-15-31","device_date_time":"2021-08-02 15:34","timestamp":"1111-11-11T11:11:11Z"}
|
||||
// |MyElement2;90919293;97;2020-12-31;270;1111-11-11 11:11.11
|
||||
|
||||
// Comment: Another version of the heat cost allocator. But for historical reasons got its
|
||||
// own driver name, which is now aliased to qcaloric.
|
||||
// Test: HCA whe5x 91835132 NOKEY
|
||||
// telegram=|244465323251839134087a4f0000000b6e0403004b6e660300426c9e29326cffff046d1416b921dd2f|
|
||||
// {"media":"heat cost allocation","meter":"qcaloric","name":"HCA","id":"91835132","status":"OK","current_consumption_hca":304,"set_date":"2020-09-30","consumption_at_set_date_hca":366,"set_date_1":"2020-09-30","consumption_at_set_date_1_hca":366,"error_date":"2127-15-31","device_date_time":"2021-01-25 22:20","timestamp":"1111-11-11T11:11:11Z"}
|
||||
// |HCA;91835132;304;2020-09-30;366;1111-11-11 11:11.11
|
||||
|
|
|
|||
|
|
@ -1,126 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 2019-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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include"meters_common_implementation.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
struct Driver : public virtual MeterCommonImplementation
|
||||
{
|
||||
Driver(MeterInfo &mi, DriverInfo &di);
|
||||
};
|
||||
|
||||
static bool ok = registerDriver([](DriverInfo&di)
|
||||
{
|
||||
di.setName("whe5x");
|
||||
di.setDefaultFields("name,id,current_consumption_hca,set_date,consumption_at_set_date_hca,timestamp");
|
||||
di.setMeterType(MeterType::HeatCostAllocationMeter);
|
||||
di.addLinkMode(LinkMode::S1);
|
||||
di.addDetection(MANUFACTURER_LSE, 0x08, 0x34);
|
||||
|
||||
di.setConstructor([](MeterInfo& mi, DriverInfo& di){ return shared_ptr<Meter>(new Driver(mi, di)); });
|
||||
});
|
||||
|
||||
Driver::Driver(MeterInfo &mi, DriverInfo &di) : MeterCommonImplementation(mi, di)
|
||||
{
|
||||
addStringField(
|
||||
"status",
|
||||
"Meter status from tpl status field.",
|
||||
PrintProperty::JSON | PrintProperty::FIELD | PrintProperty::IMPORTANT |
|
||||
PrintProperty::STATUS | PrintProperty::JOIN_TPL_STATUS);
|
||||
|
||||
addNumericFieldWithExtractor(
|
||||
"current_consumption",
|
||||
"The current temperature.",
|
||||
PrintProperty::JSON | PrintProperty::FIELD,
|
||||
Quantity::HCA,
|
||||
VifScaling::Auto,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::HeatCostAllocation)
|
||||
);
|
||||
|
||||
addStringFieldWithExtractor(
|
||||
"set_date",
|
||||
"The most recent billing period date.",
|
||||
PrintProperty::JSON | PrintProperty::FIELD,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Date)
|
||||
.set(StorageNr(1))
|
||||
);
|
||||
|
||||
addNumericFieldWithExtractor(
|
||||
"consumption_at_set_date",
|
||||
"Heat cost allocation at the most recent billing period date.",
|
||||
PrintProperty::JSON | PrintProperty::FIELD,
|
||||
Quantity::HCA,
|
||||
VifScaling::Auto,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::HeatCostAllocation)
|
||||
.set(StorageNr(1))
|
||||
);
|
||||
|
||||
addStringFieldWithExtractor(
|
||||
"set_date_1",
|
||||
"The most recent billing period date.",
|
||||
PrintProperty::JSON | PrintProperty::FIELD,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Date)
|
||||
.set(StorageNr(1))
|
||||
);
|
||||
|
||||
addNumericFieldWithExtractor(
|
||||
"consumption_at_set_date_1",
|
||||
"Heat cost allocation at the most recent billing period date.",
|
||||
PrintProperty::JSON | PrintProperty::FIELD,
|
||||
Quantity::HCA,
|
||||
VifScaling::Auto,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::HeatCostAllocation)
|
||||
.set(StorageNr(1))
|
||||
);
|
||||
|
||||
addStringFieldWithExtractor(
|
||||
"error_date",
|
||||
"Date when the meter entered an error state.",
|
||||
PrintProperty::JSON,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::AtError)
|
||||
.set(VIFRange::Date)
|
||||
);
|
||||
|
||||
addStringFieldWithExtractor(
|
||||
"device_date_time",
|
||||
"Date and time when the meter sent the telegram.",
|
||||
PrintProperty::JSON,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::DateTime)
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Test: HCA whe5x 91835132 NOKEY
|
||||
// telegram=|244465323251839134087a4f0000000b6e0403004b6e660300426c9e29326cffff046d1416b921dd2f|
|
||||
// {"media":"heat cost allocation","meter":"whe5x","name":"HCA","id":"91835132","status":"OK","current_consumption_hca":304,"set_date":"2020-09-30","consumption_at_set_date_hca":366,"set_date_1":"2020-09-30","consumption_at_set_date_1_hca":366,"error_date":"2127-15-31","device_date_time":"2021-01-25 22:20","timestamp":"1111-11-11T11:11:11Z"}
|
||||
// |HCA;91835132;304;2020-09-30;366;1111-11-11 11:11.11
|
||||
|
|
@ -1225,3 +1225,63 @@ const char *toString(MeasurementType mt)
|
|||
}
|
||||
return "?";
|
||||
}
|
||||
|
||||
string FieldMatcher::str()
|
||||
{
|
||||
string s = "";
|
||||
|
||||
if (match_dif_vif_key)
|
||||
{
|
||||
s = s+"DVK("+dif_vif_key.str()+") ";
|
||||
}
|
||||
|
||||
if (match_measurement_type)
|
||||
{
|
||||
s = s+"MT("+toString(measurement_type)+") ";
|
||||
}
|
||||
|
||||
if (match_vif_range)
|
||||
{
|
||||
s = s+"VR("+toString(vif_range)+") ";
|
||||
}
|
||||
|
||||
if (vif_combinables.size() > 0)
|
||||
{
|
||||
s += "Comb(";
|
||||
|
||||
for (auto vc : vif_combinables)
|
||||
{
|
||||
s = s+toString(vc)+" ";
|
||||
}
|
||||
|
||||
s.pop_back();
|
||||
s += ")";
|
||||
}
|
||||
|
||||
if (match_storage_nr)
|
||||
{
|
||||
s = s+"S("+to_string(storage_nr_from.intValue())+"-"+to_string(storage_nr_to.intValue())+") ";
|
||||
}
|
||||
|
||||
if (match_tariff_nr)
|
||||
{
|
||||
s = s+"T("+to_string(tariff_nr_from.intValue())+"-"+to_string(tariff_nr_to.intValue())+") ";
|
||||
}
|
||||
|
||||
if (match_subunit_nr)
|
||||
{
|
||||
s += "U("+to_string(subunit_nr_from.intValue())+"-"+to_string(subunit_nr_to.intValue())+") ";
|
||||
}
|
||||
|
||||
if (index_nr.intValue() != 1)
|
||||
{
|
||||
s += "I("+to_string(index_nr.intValue())+")";
|
||||
}
|
||||
|
||||
if (s.size() > 0)
|
||||
{
|
||||
s.pop_back();
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -430,6 +430,7 @@ struct FieldMatcher
|
|||
FieldMatcher &set(IndexNr i) { index_nr = i; return *this; }
|
||||
|
||||
bool matches(DVEntry &dv_entry);
|
||||
std::string str();
|
||||
};
|
||||
|
||||
bool loadFormatBytesFromSignature(uint16_t format_signature, std::vector<uchar> *format_bytes);
|
||||
|
|
|
|||
|
|
@ -1820,6 +1820,27 @@ void MeterCommonImplementation::setNumericValue(FieldInfo *fi, Unit u, double v)
|
|||
numeric_values_[pair<string,Quantity>(field_name_no_unit,fi->xuantity())] = NumericField(u, v, fi);
|
||||
}
|
||||
|
||||
bool MeterCommonImplementation::hasValue(FieldInfo *fi)
|
||||
{
|
||||
return hasStringValue(fi) || hasNumericValue(fi);
|
||||
}
|
||||
|
||||
bool MeterCommonImplementation::hasNumericValue(FieldInfo *fi)
|
||||
{
|
||||
if (fi->hasGetNumericValueOverride()) return true;
|
||||
|
||||
pair<string,Quantity> key(fi->vname(),fi->xuantity());
|
||||
|
||||
return numeric_values_.count(key) != 0;
|
||||
}
|
||||
|
||||
bool MeterCommonImplementation::hasStringValue(FieldInfo *fi)
|
||||
{
|
||||
if (fi->hasGetStringValueOverride()) return true;
|
||||
|
||||
return string_values_.count(fi->vname()) != 0;
|
||||
}
|
||||
|
||||
double MeterCommonImplementation::getNumericValue(FieldInfo *fi, Unit to)
|
||||
{
|
||||
if (fi->hasGetNumericValueOverride())
|
||||
|
|
@ -2033,12 +2054,14 @@ void MeterCommonImplementation::printMeter(Telegram *t,
|
|||
}
|
||||
|
||||
// Iterate over the meter field infos...
|
||||
map<FieldInfo*,DVEntry*> found; // Found from the telegram
|
||||
set<string> found_vnames;
|
||||
|
||||
for (FieldInfo& fi : field_infos_)
|
||||
{
|
||||
if (fi.printProperties().hasJSON())
|
||||
{
|
||||
// The field should be printed in the json. (Most usually should.)
|
||||
bool found = false;
|
||||
for (auto& i : t->dv_entries)
|
||||
{
|
||||
// Check each telegram dv entry.
|
||||
|
|
@ -2046,6 +2069,21 @@ void MeterCommonImplementation::printMeter(Telegram *t,
|
|||
// Has the entry been matches to this field, then print it as json.
|
||||
if (dve->hasFieldInfo(&fi))
|
||||
{
|
||||
assert(found.count(&fi) == 0);
|
||||
found[&fi] = dve;
|
||||
found_vnames.insert(fi.vname());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (FieldInfo& fi : field_infos_)
|
||||
{
|
||||
if (fi.printProperties().hasJSON())
|
||||
{
|
||||
if (found.count(&fi) != 0)
|
||||
{
|
||||
DVEntry *dve = found[&fi];
|
||||
debug("(meters) render field %s(%s)[%d] with dventry @%d key %s data %s\n",
|
||||
fi.vname().c_str(), toString(fi.xuantity()), fi.index(),
|
||||
dve->offset,
|
||||
|
|
@ -2054,15 +2092,26 @@ void MeterCommonImplementation::printMeter(Telegram *t,
|
|||
string out = fi.renderJson(this, &conversions());
|
||||
debug("(meters) %s\n", out.c_str());
|
||||
s += indent+out+","+newline;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if (!found && !fi.printProperties().hasOPTIONAL())
|
||||
else
|
||||
{
|
||||
// Ok, no value found in received telegram.
|
||||
// Print field anyway, if it is not OPTIONAL
|
||||
// or if a value has been received before and this field has not been received using a different rule.
|
||||
// Why this complicated rule?
|
||||
// E.g. the minmoess mbus seems to use storage 1 for target_m3 but the wmbus version uses storage 8.
|
||||
// I.e. we have two rules that store into target_m3, this check will prevent target_m3 from being printed twice.
|
||||
if (!fi.printProperties().hasOPTIONAL() || (found_vnames.count(fi.vname()) == 0 && hasValue(&fi)))
|
||||
{
|
||||
// No telegram entries found, but this field should be printed anyway.
|
||||
// It will be printed with any value received from a previous telegram.
|
||||
// Or if no value has been received, null.
|
||||
s += indent+fi.renderJson(this, &conversions())+","+newline;
|
||||
debug("(meters) render field %s(%s)[%d] without dventry\n",
|
||||
fi.vname().c_str(), toString(fi.xuantity()), fi.index());
|
||||
string out = fi.renderJson(this, &conversions());
|
||||
debug("(meters) %s\n", out.c_str());
|
||||
s += indent+out+","+newline;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2492,6 +2541,19 @@ bool FieldInfo::matches(DVEntry *dve)
|
|||
return matcher_.matches(*dve);
|
||||
}
|
||||
|
||||
string FieldInfo::str()
|
||||
{
|
||||
// 15 target Volume x<> :<3A> Auto XUZ "The total water consumption recorded at the beginning of this month."
|
||||
return tostrprintf("%d %s_%s (%s) %s [%s] \"%s\"",
|
||||
index_,
|
||||
vname_.c_str(),
|
||||
unitToStringLowerCase(default_unit_).c_str(),
|
||||
toString(xuantity_),
|
||||
toString(vif_scaling_),
|
||||
matcher_.str().c_str(),
|
||||
help_.c_str());
|
||||
}
|
||||
|
||||
DriverName MeterInfo::driverName()
|
||||
{
|
||||
if (driver_name.str() == "")
|
||||
|
|
@ -2923,6 +2985,17 @@ void MeterCommonImplementation::addOptionalFlowRelatedFields()
|
|||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::VolumeFlow)
|
||||
);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
const char *toString(VifScaling s)
|
||||
{
|
||||
switch (s)
|
||||
{
|
||||
case VifScaling::None: return "None";
|
||||
case VifScaling::Auto: return "Auto";
|
||||
case VifScaling::NoneSigned: return "NoneSigned";
|
||||
case VifScaling::AutoSigned: return "AutoSigned";
|
||||
}
|
||||
return "?";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -288,6 +288,8 @@ enum class VifScaling
|
|||
AutoSigned // Scale and assume the value is signed.
|
||||
};
|
||||
|
||||
const char* toString(VifScaling s);
|
||||
|
||||
enum PrintProperty
|
||||
{
|
||||
JSON = 1, // This field should be printed when using --format=json
|
||||
|
|
@ -382,10 +384,13 @@ struct FieldInfo
|
|||
// The vname is then a pattern total_at_month_{storagenr-32} that gets translated into
|
||||
// total_at_month_2 (for the dventry with storage nr 34.)
|
||||
string generateFieldName(DVEntry *dve);
|
||||
|
||||
// Check if the meter object stores a value for this field.
|
||||
bool hasValue(Meter *m);
|
||||
|
||||
Translate::Lookup& lookup() { return lookup_; }
|
||||
|
||||
string str();
|
||||
|
||||
private:
|
||||
|
||||
int index_; // The field infos for a meter are ordered.
|
||||
|
|
|
|||
|
|
@ -231,6 +231,12 @@ protected:
|
|||
double getNumericValue(FieldInfo *fi, Unit u);
|
||||
void setStringValue(FieldInfo *fi, std::string v);
|
||||
std::string getStringValue(FieldInfo *fi);
|
||||
|
||||
// Check if the meter has received a value for this field.
|
||||
bool hasValue(FieldInfo *fi);
|
||||
bool hasNumericValue(FieldInfo *fi);
|
||||
bool hasStringValue(FieldInfo *fi);
|
||||
|
||||
std::string decodeTPLStatusByte(uchar sts);
|
||||
|
||||
void addOptionalCommonFields();
|
||||
|
|
|
|||
Ładowanie…
Reference in New Issue