kopia lustrzana https://github.com/weetmuts/wmbusmeters
Add search for AnyEnergyVIF and refactor sharky774 driver using this feature.
rodzic
e3fde0316c
commit
d4e367aa48
2
CHANGES
2
CHANGES
|
@ -1,4 +1,6 @@
|
|||
|
||||
The sharky774 was improved to handle more different meter configurations.
|
||||
|
||||
Michael Ott fixed a bug in oneshot. Thanks Michael!
|
||||
|
||||
Fix bug in mode 7 decryption when the encrypted data was followed by non-encrypted data.
|
||||
|
|
|
@ -233,6 +233,7 @@ As {options} you can use:
|
|||
--meterfilestimestamp=(never|day|hour|minute|micros) the meter file is suffixed with a
|
||||
timestamp (localtime) with the given resolution.
|
||||
--nodeviceexit if no wmbus devices are found, then exit immediately
|
||||
--normal for normal logging
|
||||
--oneshot wait for an update from each meter, then quit
|
||||
--resetafter=<time> reset the wmbus dongle regularly, default is 23h
|
||||
--selectfields=id,timestamp,total_m3 select only these fields to be printed (--listfields=<meter> to list available fields)
|
||||
|
|
|
@ -248,9 +248,9 @@ telegram=||9e44731e17011020010278046d0813bc2104030000000084100300000000842003000
|
|||
|Gran301;20100117;0.000000;234.100000;0.000000;0.000000;0.000000;0.000000;0.000000;50.000000;OK;1111-11-11 11:11.11
|
||||
|
||||
# Test Hydrometer/Diehl Metering Sharky 774 heat meter
|
||||
telegram=||5E44A5112751617241047A8B0050052F2F0C0E000000000C13010000000B3B0000000C2B000000000A5A26020A5E18020B260321000AA6180000C2026CBE2BCC020E00000000CC021301000000DB023B000000DC022B000000002F2F2F2F2F|
|
||||
{"media":"heat","meter":"sharky774","name":"Sharky774","id":"72615127","total_energy_consumption_kwh":0,"total_volume_m3":0.001,"volume_flow_m3h":0,"power_kw":0,"flow_temperature_c":22.6,"return_temperature_c":21.8,"temperature_difference_c":0.8,"timestamp":"1111-11-11T11:11:11Z"}
|
||||
|Sharky774;72615127;0.000000;0.001000;0.000000;0.000000;22.600000;21.800000;0.800000;1111-11-11 11:11.11
|
||||
telegram=|5E44A5112751617241047A8B0050052F2F0C0E000000000C13010000000B3B0000000C2B000000000A5A26020A5E18020B260321000AA6180000C2026CBE2BCC020E00000000CC021301000000DB023B000000DC022B000000002F2F2F2F2F|
|
||||
{"media":"heat","meter":"sharky774","name":"Sharky774","id":"72615127","total_energy_consumption_kwh":0,"total_volume_m3":0.001,"volume_flow_m3h":0,"power_kw":0,"flow_temperature_c":22.6,"return_temperature_c":21.8,"temperature_difference_c":0.8,"operating_time_h":0,"energy_at_set_date_kwh":0,"set_date":"","timestamp":"1111-11-11T11:11:11Z"}
|
||||
|Sharky774;72615127;0.000000;0.001000;0.000000;0.000000;22.600000;21.800000;0.800000;0.000000;1111-11-11 11:11.11
|
||||
|
||||
# Test Hydrometer/Diehl Metering Sharky 775 heat meter
|
||||
telegram=|534424232004256092687A370045752235854DEEEA5939FAD81C25FEEF5A23C38FB9168493C563F08DB10BAF87F660FBA91296BA2397E8F4220B86D3A192FB51E0BFCF24DCE72118E0C75A9E89F43BDFE370824B|
|
||||
|
|
|
@ -77,6 +77,14 @@ static shared_ptr<Configuration> parseNormalCommandLine(Configuration *c, int ar
|
|||
i++;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(argv[i], "--normal")) {
|
||||
c->silent = false;
|
||||
c->verbose = false;
|
||||
c->debug = false;
|
||||
c->trace = false;
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(argv[i], "--version")) {
|
||||
c->version = true;
|
||||
return shared_ptr<Configuration>(c);
|
||||
|
|
|
@ -0,0 +1,202 @@
|
|||
/*
|
||||
Copyright (C) 2021 Vincent Privat (gpl-3.0-or-later)
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include"meters_common_implementation.h"
|
||||
|
||||
struct MeterSharky774 : public virtual MeterCommonImplementation
|
||||
{
|
||||
MeterSharky774(MeterInfo &mi, DriverInfo &di);
|
||||
|
||||
private:
|
||||
|
||||
double total_energy_consumption_kwh_ {};
|
||||
double total_volume_m3_ {};
|
||||
double volume_flow_m3h_ {};
|
||||
double power_kw_ {};
|
||||
double flow_temperature_c_ {};
|
||||
double return_temperature_c_ {};
|
||||
double energy_at_set_date_kwh_ {};
|
||||
double operating_time_h_ {};
|
||||
string set_date_txt_;
|
||||
};
|
||||
|
||||
static bool ok = registerDriver([](DriverInfo&di)
|
||||
{
|
||||
di.setName("sharky774");
|
||||
di.setMeterType(MeterType::HeatMeter);
|
||||
di.setExpectedTPLSecurityMode(TPLSecurityMode::AES_CBC_IV);
|
||||
di.addLinkMode(LinkMode::T1);
|
||||
di.addDetection(MANUFACTURER_DME, 0x04, 0x41);
|
||||
di.setConstructor([](MeterInfo& mi, DriverInfo& di){ return shared_ptr<Meter>(new MeterSharky774(mi, di)); });
|
||||
});
|
||||
|
||||
MeterSharky774::MeterSharky774(MeterInfo &mi, DriverInfo &di) : MeterCommonImplementation(mi, di)
|
||||
{
|
||||
addFieldWithExtractor(
|
||||
"total_energy_consumption",
|
||||
Quantity::Energy,
|
||||
NoDifVifKey,
|
||||
VifScaling::Auto,
|
||||
MeasurementType::Instantaneous,
|
||||
ValueInformation::AnyEnergyVIF,
|
||||
StorageNr(0),
|
||||
TariffNr(0),
|
||||
IndexNr(1),
|
||||
PrintProperty::JSON | PrintProperty::FIELD | PrintProperty::IMPORTANT,
|
||||
"The total energy consumption recorded by this meter.",
|
||||
SET_FUNC(total_energy_consumption_kwh_, Unit::KWH),
|
||||
GET_FUNC(total_energy_consumption_kwh_, Unit::KWH));
|
||||
|
||||
addFieldWithExtractor(
|
||||
"total_volume",
|
||||
Quantity::Volume,
|
||||
NoDifVifKey,
|
||||
VifScaling::Auto,
|
||||
MeasurementType::Instantaneous,
|
||||
ValueInformation::AnyVolumeVIF,
|
||||
StorageNr(0),
|
||||
TariffNr(0),
|
||||
IndexNr(1),
|
||||
PrintProperty::JSON | PrintProperty::FIELD,
|
||||
"The total volume recorded by this meter.",
|
||||
SET_FUNC(total_volume_m3_, Unit::M3),
|
||||
GET_FUNC(total_volume_m3_, Unit::M3));
|
||||
|
||||
addFieldWithExtractor(
|
||||
"volume_flow",
|
||||
Quantity::Flow,
|
||||
NoDifVifKey,
|
||||
VifScaling::Auto,
|
||||
MeasurementType::Instantaneous,
|
||||
ValueInformation::VolumeFlow,
|
||||
StorageNr(0),
|
||||
TariffNr(0),
|
||||
IndexNr(1),
|
||||
PrintProperty::JSON | PrintProperty::FIELD,
|
||||
"The current flow.",
|
||||
SET_FUNC(volume_flow_m3h_, Unit::M3H),
|
||||
GET_FUNC(volume_flow_m3h_, Unit::M3H));
|
||||
|
||||
addFieldWithExtractor(
|
||||
"power",
|
||||
Quantity::Power,
|
||||
NoDifVifKey,
|
||||
VifScaling::Auto,
|
||||
MeasurementType::Instantaneous,
|
||||
ValueInformation::AnyPowerVIF,
|
||||
StorageNr(0),
|
||||
TariffNr(0),
|
||||
IndexNr(1),
|
||||
PrintProperty::JSON | PrintProperty::FIELD,
|
||||
"The power.",
|
||||
SET_FUNC(power_kw_, Unit::KW),
|
||||
GET_FUNC(power_kw_, Unit::KW));
|
||||
|
||||
addFieldWithExtractor(
|
||||
"flow_temperature",
|
||||
Quantity::Temperature,
|
||||
NoDifVifKey,
|
||||
VifScaling::Auto,
|
||||
MeasurementType::Instantaneous,
|
||||
ValueInformation::FlowTemperature,
|
||||
StorageNr(0),
|
||||
TariffNr(0),
|
||||
IndexNr(1),
|
||||
PrintProperty::JSON | PrintProperty::FIELD,
|
||||
"The flow temperature.",
|
||||
SET_FUNC(flow_temperature_c_, Unit::C),
|
||||
GET_FUNC(flow_temperature_c_, Unit::C));
|
||||
|
||||
addFieldWithExtractor(
|
||||
"return_temperature",
|
||||
Quantity::Temperature,
|
||||
NoDifVifKey,
|
||||
VifScaling::Auto,
|
||||
MeasurementType::Instantaneous,
|
||||
ValueInformation::ReturnTemperature,
|
||||
StorageNr(0),
|
||||
TariffNr(0),
|
||||
IndexNr(1),
|
||||
PrintProperty::JSON | PrintProperty::FIELD,
|
||||
"The return temperature.",
|
||||
SET_FUNC(return_temperature_c_, Unit::C),
|
||||
GET_FUNC(return_temperature_c_, Unit::C));
|
||||
|
||||
addField("temperature_difference",
|
||||
Quantity::Temperature,
|
||||
PrintProperty::JSON | PrintProperty::FIELD,
|
||||
"The temperature difference.",
|
||||
[](Unit u, double v) {},
|
||||
[this](Unit u) { return flow_temperature_c_ - return_temperature_c_; });
|
||||
|
||||
addFieldWithExtractor(
|
||||
"operating_time",
|
||||
Quantity::Time,
|
||||
DifVifKey("0AA618"),
|
||||
VifScaling::Auto,
|
||||
MeasurementType::Unknown,
|
||||
ValueInformation::None,
|
||||
StorageNr(0),
|
||||
TariffNr(0),
|
||||
IndexNr(1),
|
||||
PrintProperty::JSON,
|
||||
"The operating time.",
|
||||
SET_FUNC(operating_time_h_, Unit::Hour),
|
||||
GET_FUNC(operating_time_h_, Unit::Hour));
|
||||
|
||||
addFieldWithExtractor(
|
||||
"energy_at_set_date",
|
||||
Quantity::Energy,
|
||||
NoDifVifKey,
|
||||
VifScaling::Auto,
|
||||
MeasurementType::Instantaneous,
|
||||
ValueInformation::AnyEnergyVIF,
|
||||
StorageNr(1),
|
||||
TariffNr(0),
|
||||
IndexNr(1),
|
||||
PrintProperty::JSON | PrintProperty::FIELD,
|
||||
"The total energy consumption recorded by this meter at the set date.",
|
||||
SET_FUNC(energy_at_set_date_kwh_, Unit::KWH),
|
||||
GET_FUNC(energy_at_set_date_kwh_, Unit::KWH));
|
||||
|
||||
addStringFieldWithExtractor(
|
||||
"set_date",
|
||||
Quantity::Text,
|
||||
NoDifVifKey,
|
||||
MeasurementType::Instantaneous,
|
||||
ValueInformation::Date,
|
||||
StorageNr(1),
|
||||
TariffNr(0),
|
||||
IndexNr(1),
|
||||
PrintProperty::JSON,
|
||||
"The last billing set date.",
|
||||
SET_STRING_FUNC(set_date_txt_),
|
||||
GET_STRING_FUNC(set_date_txt_));
|
||||
|
||||
}
|
||||
|
||||
// Test: Heato sharky774 58496405 NOKEY
|
||||
// telegram=3E44A5110564495841047A700030052F2F#0C06846800000C13195364000B3B0400000C2B110100000A5A17050A5E76020AA61800004C0647630000426CBF25
|
||||
// {"media":"heat","meter":"sharky774","name":"Heato","id":"58496405","total_energy_consumption_kwh":6884,"total_volume_m3":645.319,"volume_flow_m3h":0.004,"power_kw":0.111,"flow_temperature_c":51.7,"return_temperature_c":27.6,"temperature_difference_c":24.1,"operating_time_h":0,"energy_at_set_date_kwh":6347,"set_date":"2021-05-31","timestamp":"1111-11-11T11:11:11Z"}
|
||||
// |Heato;58496405;6884.000000;645.319000;0.004000;0.111000;51.700000;27.600000;24.100000;6347.000000;1111-11-11 11:11.11
|
||||
|
||||
// This test telegram has more historical data!
|
||||
// Test: Heatoo sharky774 72615127 NOKEY
|
||||
// telegram=|5E44A5112751617241047A8B0050052F2F0C0E000000000C13010000000B3B0000000C2B000000000A5A26020A5E18020B260321000AA6180000C2026CBE2BCC020E00000000CC021301000000DB023B000000DC022B000000002F2F2F2F2F|
|
||||
// {"media":"heat","meter":"sharky774","name":"Heatoo","id":"72615127","total_energy_consumption_kwh":0,"total_volume_m3":0.001,"volume_flow_m3h":0,"power_kw":0,"flow_temperature_c":22.6,"return_temperature_c":21.8,"temperature_difference_c":0.8,"operating_time_h":0,"energy_at_set_date_kwh":0,"set_date":"","timestamp":"1111-11-11T11:11:11Z"}
|
||||
// |Heatoo;72615127;0.000000;0.001000;0.000000;0.000000;22.600000;21.800000;0.800000;0.000000;1111-11-11 11:11.11
|
|
@ -342,6 +342,36 @@ LIST_OF_VALUETYPES
|
|||
assert(0);
|
||||
}
|
||||
|
||||
bool matchSingleVif(int vi, ValueInformation vif)
|
||||
{
|
||||
int low, hi;
|
||||
valueInfoRange(vif, &low, &hi);
|
||||
|
||||
return vi >= low && vi <= hi;
|
||||
}
|
||||
|
||||
bool isVIFMatch(int vi, ValueInformation vif)
|
||||
{
|
||||
if (vif == ValueInformation::AnyVolumeVIF)
|
||||
{
|
||||
// There are more volume units in the standard that will be added here.
|
||||
return matchSingleVif(vi, ValueInformation::Volume);
|
||||
}
|
||||
if (vif == ValueInformation::AnyEnergyVIF)
|
||||
{
|
||||
return
|
||||
matchSingleVif(vi, ValueInformation::EnergyWh) ||
|
||||
matchSingleVif(vi, ValueInformation::EnergyMJ);
|
||||
}
|
||||
if (vif == ValueInformation::AnyPowerVIF)
|
||||
{
|
||||
// There are more power units in the standard that will be added here.
|
||||
return matchSingleVif(vi, ValueInformation::PowerW);
|
||||
}
|
||||
|
||||
return matchSingleVif(vi, vif);
|
||||
}
|
||||
|
||||
bool hasKey(std::map<std::string,std::pair<int,DVEntry>> *values, std::string key)
|
||||
{
|
||||
return values->count(key) > 0;
|
||||
|
@ -356,9 +386,6 @@ bool findKey(MeasurementType mit, ValueInformation vif, int storagenr, int tarif
|
|||
bool findKeyWithNr(MeasurementType mit, ValueInformation vif, int storagenr, int tariffnr, int nr,
|
||||
std::string *key, std::map<std::string,std::pair<int,DVEntry>> *values)
|
||||
{
|
||||
int low, hi;
|
||||
valueInfoRange(vif, &low, &hi);
|
||||
|
||||
/*debug("(dvparser) looking for type=%s vif=%s storagenr=%d value_ran_low=%02x value_ran_hi=%02x\n",
|
||||
measurementTypeName(mit).c_str(), toString(vif), storagenr,
|
||||
low, hi);*/
|
||||
|
@ -373,10 +400,10 @@ bool findKeyWithNr(MeasurementType mit, ValueInformation vif, int storagenr, int
|
|||
v.first.c_str(),
|
||||
measurementTypeName(ty).c_str(), vi, toString(toValueInformation(vi)), storagenr, sn);*/
|
||||
|
||||
if (vi >= low && vi <= hi
|
||||
&& (mit == MeasurementType::Unknown || mit == ty)
|
||||
&& (storagenr == ANY_STORAGENR || storagenr == sn)
|
||||
&& (tariffnr == ANY_TARIFFNR || tariffnr == tn))
|
||||
if (isVIFMatch(vi, vif) &&
|
||||
(mit == MeasurementType::Unknown || mit == ty) &&
|
||||
(storagenr == ANY_STORAGENR || storagenr == sn) &&
|
||||
(tariffnr == ANY_TARIFFNR || tariffnr == tn))
|
||||
{
|
||||
*key = v.first;
|
||||
nr--;
|
||||
|
|
|
@ -44,6 +44,9 @@
|
|||
X(PowerW,0x28,0x2f, Quantity::Power, Unit::KW) \
|
||||
X(ActualityDuration,0x74,0x77, Quantity::Time, Unit::Second) \
|
||||
X(EnhancedIdentification,0x79,0x79, Quantity::Text, Unit::TXT) \
|
||||
X(AnyVolumeVIF,0x00,0x00, Quantity::Volume, Unit::Unknown) \
|
||||
X(AnyEnergyVIF,0x00,0x00, Quantity::Energy, Unit::Unknown) \
|
||||
X(AnyPowerVIF,0x00,0x00, Quantity::Power, Unit::Unknown) \
|
||||
|
||||
enum class ValueInformation
|
||||
{
|
||||
|
|
|
@ -104,7 +104,6 @@
|
|||
X(QHEAT, MANUFACTURER_QDS, 0x04, 0x23) \
|
||||
X(QSMOKE, MANUFACTURER_QDS, 0x1a, 0x21) \
|
||||
X(QSMOKE, MANUFACTURER_QDS, 0x1a, 0x23) \
|
||||
X(SHARKY774, MANUFACTURER_DME, 0x04, 0x41) \
|
||||
X(SONTEX868, MANUFACTURER_SON, 0x08, 0x16) \
|
||||
X(TOPASESKR, MANUFACTURER_AMT, 0x06, 0xf1) \
|
||||
X(TOPASESKR, MANUFACTURER_AMT, 0x07, 0xf1) \
|
||||
|
|
|
@ -1,222 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 2021 Vincent Privat (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.h"
|
||||
#include"meters_common_implementation.h"
|
||||
#include"dvparser.h"
|
||||
#include"wmbus.h"
|
||||
#include"wmbus_utils.h"
|
||||
|
||||
struct MeterSharky774 : public virtual MeterCommonImplementation {
|
||||
MeterSharky774(MeterInfo &mi);
|
||||
|
||||
double totalEnergyConsumption(Unit u);
|
||||
double totalVolume(Unit u);
|
||||
double volumeFlow(Unit u);
|
||||
double power(Unit u);
|
||||
double flowTemperature(Unit u);
|
||||
double returnTemperature(Unit u);
|
||||
double temperatureDifference(Unit u);
|
||||
|
||||
private:
|
||||
void processContent(Telegram *t);
|
||||
|
||||
double total_energy_mj_ {};
|
||||
double total_volume_m3_ {};
|
||||
double volume_flow_m3h_ {};
|
||||
double power_w_ {};
|
||||
double flow_temperature_c_ {};
|
||||
double return_temperature_c_ {};
|
||||
};
|
||||
|
||||
MeterSharky774::MeterSharky774(MeterInfo &mi) :
|
||||
MeterCommonImplementation(mi, "sharky774")
|
||||
{
|
||||
setMeterType(MeterType::HeatMeter);
|
||||
|
||||
addLinkMode(LinkMode::T1);
|
||||
|
||||
addPrint("total_energy_consumption", Quantity::Energy,
|
||||
[&](Unit u){ return totalEnergyConsumption(u); },
|
||||
"The total energy consumption recorded by this meter.",
|
||||
true, true);
|
||||
|
||||
addPrint("total_volume", Quantity::Volume,
|
||||
[&](Unit u){ return totalVolume(u); },
|
||||
"The total volume recorded by this meter.",
|
||||
true, true);
|
||||
|
||||
addPrint("volume_flow", Quantity::Flow,
|
||||
[&](Unit u){ return volumeFlow(u); },
|
||||
"The current flow.",
|
||||
true, true);
|
||||
|
||||
addPrint("power", Quantity::Power,
|
||||
[&](Unit u){ return power(u); },
|
||||
"The power.",
|
||||
true, true);
|
||||
|
||||
addPrint("flow_temperature", Quantity::Temperature,
|
||||
[&](Unit u){ return flowTemperature(u); },
|
||||
"The flow temperature.",
|
||||
true, true);
|
||||
|
||||
addPrint("return_temperature", Quantity::Temperature,
|
||||
[&](Unit u){ return returnTemperature(u); },
|
||||
"The return temperature.",
|
||||
true, true);
|
||||
|
||||
addPrint("temperature_difference", Quantity::Temperature,
|
||||
[&](Unit u){ return temperatureDifference(u); },
|
||||
"The temperature difference.",
|
||||
true, true);
|
||||
}
|
||||
|
||||
shared_ptr<Meter> createSharky774(MeterInfo &mi) {
|
||||
return shared_ptr<Meter>(new MeterSharky774(mi));
|
||||
}
|
||||
|
||||
double MeterSharky774::totalEnergyConsumption(Unit u)
|
||||
{
|
||||
assertQuantity(u, Quantity::Energy);
|
||||
return convert(total_energy_mj_, Unit::MJ, u);
|
||||
}
|
||||
|
||||
double MeterSharky774::totalVolume(Unit u)
|
||||
{
|
||||
assertQuantity(u, Quantity::Volume);
|
||||
return convert(total_volume_m3_, Unit::M3, u);
|
||||
}
|
||||
|
||||
double MeterSharky774::volumeFlow(Unit u)
|
||||
{
|
||||
assertQuantity(u, Quantity::Flow);
|
||||
return convert(volume_flow_m3h_, Unit::M3H, u);
|
||||
}
|
||||
|
||||
double MeterSharky774::power(Unit u)
|
||||
{
|
||||
assertQuantity(u, Quantity::Power);
|
||||
return convert(power_w_, Unit::KW, u);
|
||||
}
|
||||
|
||||
double MeterSharky774::flowTemperature(Unit u)
|
||||
{
|
||||
assertQuantity(u, Quantity::Temperature);
|
||||
return convert(flow_temperature_c_, Unit::C, u);
|
||||
}
|
||||
|
||||
double MeterSharky774::returnTemperature(Unit u)
|
||||
{
|
||||
assertQuantity(u, Quantity::Temperature);
|
||||
return convert(return_temperature_c_, Unit::C, u);
|
||||
}
|
||||
|
||||
double MeterSharky774::temperatureDifference(Unit u)
|
||||
{
|
||||
assertQuantity(u, Quantity::Temperature);
|
||||
return convert(flow_temperature_c_ - return_temperature_c_, Unit::C, u);
|
||||
}
|
||||
|
||||
void MeterSharky774::processContent(Telegram *t)
|
||||
{
|
||||
/*
|
||||
(sharky) 017 : 0C dif (8 digit BCD Instantaneous value)
|
||||
(sharky) 018 : 0E vif (Energy MJ)
|
||||
(sharky) 019 C?: 00000000
|
||||
(sharky) 023 : 0C dif (8 digit BCD Instantaneous value)
|
||||
(sharky) 024 : 13 vif (Volume l)
|
||||
(sharky) 025 C!: 00000000 total volume (0.000000 ㎥)
|
||||
(sharky) 029 : 0B dif (6 digit BCD Instantaneous value)
|
||||
(sharky) 030 : 3B vif (Volume flow l/h)
|
||||
(sharky) 031 C!: 000000 volume flow (0.000000 ㎥/h)
|
||||
(sharky) 034 : 0C dif (8 digit BCD Instantaneous value)
|
||||
(sharky) 035 : 2B vif (Power W)
|
||||
(sharky) 036 C!: 00000000 power (0.000000 W)
|
||||
(sharky) 040 : 0A dif (4 digit BCD Instantaneous value)
|
||||
(sharky) 041 : 5A vif (Flow temperature 10⁻¹ °C)
|
||||
(sharky) 042 C!: 8504 flow temperature (48.500000 °C)
|
||||
(sharky) 044 : 0A dif (4 digit BCD Instantaneous value)
|
||||
(sharky) 045 : 5E vif (Return temperature 10⁻¹ °C)
|
||||
(sharky) 046 C!: 6604 return temperature (46.600000 °C)
|
||||
(sharky) 048 : 0B dif (6 digit BCD Instantaneous value)
|
||||
(sharky) 049 : 26 vif (Operating time hours)
|
||||
(sharky) 050 C?: 631800
|
||||
(sharky) 053 : 0A dif (4 digit BCD Instantaneous value)
|
||||
(sharky) 054 : A6 vif (Operating time hours)
|
||||
(sharky) 055 : 18 vife (?)
|
||||
(sharky) 056 C?: 0000
|
||||
(sharky) 058 : C2 dif (16 Bit Integer/Binary Instantaneous value storagenr=1)
|
||||
(sharky) 059 : 02 dife (subunit=0 tariff=0 storagenr=5)
|
||||
(sharky) 060 : 6C vif (Date type G)
|
||||
(sharky) 061 C?: BE2B
|
||||
(sharky) 063 : CC dif (8 digit BCD Instantaneous value storagenr=1)
|
||||
(sharky) 064 : 02 dife (subunit=0 tariff=0 storagenr=5)
|
||||
(sharky) 065 : 0E vif (Energy MJ)
|
||||
(sharky) 066 C?: 00000000
|
||||
(sharky) 070 : CC dif (8 digit BCD Instantaneous value storagenr=1)
|
||||
(sharky) 071 : 02 dife (subunit=0 tariff=0 storagenr=5)
|
||||
(sharky) 072 : 13 vif (Volume l)
|
||||
(sharky) 073 C?: 00000000
|
||||
(sharky) 077 : DB dif (6 digit BCD Maximum value storagenr=1)
|
||||
(sharky) 078 : 02 dife (subunit=0 tariff=0 storagenr=5)
|
||||
(sharky) 079 : 3B vif (Volume flow l/h)
|
||||
(sharky) 080 C?: 000000
|
||||
(sharky) 083 : DC dif (8 digit BCD Maximum value storagenr=1)
|
||||
(sharky) 084 : 02 dife (subunit=0 tariff=0 storagenr=5)
|
||||
(sharky) 085 : 2B vif (Power W)
|
||||
(sharky) 086 C?: 00000000
|
||||
(sharky) 090 : 2F skip
|
||||
(sharky) 091 : 2F skip
|
||||
(sharky) 092 : 2F skip
|
||||
(sharky) 093 : 2F skip
|
||||
(sharky) 094 : 2F skip
|
||||
*/
|
||||
|
||||
int offset;
|
||||
string key;
|
||||
|
||||
if (findKey(MeasurementType::Instantaneous, ValueInformation::EnergyMJ, 0, 0, &key, &t->values)) {
|
||||
extractDVdouble(&t->values, key, &offset, &total_energy_mj_);
|
||||
t->addMoreExplanation(offset, " total energy consumption (%f MJ)", total_energy_mj_);
|
||||
}
|
||||
|
||||
if (findKey(MeasurementType::Instantaneous, ValueInformation::Volume, 0, 0, &key, &t->values)) {
|
||||
extractDVdouble(&t->values, key, &offset, &total_volume_m3_);
|
||||
t->addMoreExplanation(offset, " total volume (%f ㎥)", total_volume_m3_);
|
||||
}
|
||||
|
||||
if (findKey(MeasurementType::Instantaneous, ValueInformation::VolumeFlow, 0, 0, &key, &t->values)) {
|
||||
extractDVdouble(&t->values, key, &offset, &volume_flow_m3h_);
|
||||
t->addMoreExplanation(offset, " volume flow (%f ㎥/h)", volume_flow_m3h_);
|
||||
}
|
||||
|
||||
if (findKey(MeasurementType::Instantaneous, ValueInformation::PowerW, 0, 0, &key, &t->values)) {
|
||||
extractDVdouble(&t->values, key, &offset, &power_w_);
|
||||
t->addMoreExplanation(offset, " power (%f W)", power_w_);
|
||||
}
|
||||
|
||||
if (findKey(MeasurementType::Instantaneous, ValueInformation::FlowTemperature, 0, 0, &key, &t->values)) {
|
||||
extractDVdouble(&t->values, key, &offset, &flow_temperature_c_);
|
||||
t->addMoreExplanation(offset, " flow temperature (%f °C)", flow_temperature_c_);
|
||||
}
|
||||
|
||||
if (findKey(MeasurementType::Instantaneous, ValueInformation::ReturnTemperature, 0, 0, &key, &t->values)) {
|
||||
extractDVdouble(&t->values, key, &offset, &return_temperature_c_);
|
||||
t->addMoreExplanation(offset, " return temperature (%f °C)", return_temperature_c_);
|
||||
}
|
||||
}
|
|
@ -898,6 +898,9 @@ void MeterCommonImplementation::addFieldWithExtractor(
|
|||
{
|
||||
Unit decoded_unit = fi->defaultUnit();
|
||||
if (fi->valueInformation() != ValueInformation::Any &&
|
||||
fi->valueInformation() != ValueInformation::AnyVolumeVIF &&
|
||||
fi->valueInformation() != ValueInformation::AnyEnergyVIF &&
|
||||
fi->valueInformation() != ValueInformation::AnyPowerVIF &&
|
||||
fi->valueInformation() != ValueInformation::None)
|
||||
{
|
||||
decoded_unit = toDefaultUnit(fi->valueInformation());
|
||||
|
|
|
@ -102,7 +102,6 @@ LIST_OF_METER_TYPES
|
|||
X(qheat, T1_bit, HeatMeter, QHEAT, QHeat) \
|
||||
X(qsmoke, T1_bit, SmokeDetector, QSMOKE, QSmoke) \
|
||||
X(sensostar, C1_bit|T1_bit, HeatMeter,SENSOSTAR, Sensostar) \
|
||||
X(sharky774, T1_bit, HeatMeter, SHARKY774, Sharky774) \
|
||||
X(sontex868, T1_bit, HeatCostAllocationMeter, SONTEX868, Sontex868) \
|
||||
X(topaseskr, T1_bit, WaterMeter, TOPASESKR, TopasEsKr) \
|
||||
X(ultrimis, T1_bit, WaterMeter, ULTRIMIS, Ultrimis) \
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
#include"units.h"
|
||||
#include"util.h"
|
||||
#include<assert.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
@ -69,7 +70,11 @@ double convert(double vfrom, Unit ufrom, Unit uto)
|
|||
LIST_OF_CONVERSIONS
|
||||
#undef X
|
||||
|
||||
error("Cannot convert between units!\n");
|
||||
string from = unitToStringHR(ufrom);
|
||||
string to = unitToStringHR(uto);
|
||||
|
||||
fprintf(stderr, "Cannot convert between units! %s %s\n", from.c_str(), to.c_str());
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -89,6 +89,8 @@ Add :verbose to any analyze to get more verbose analyze output.
|
|||
|
||||
\fB\--nodeviceexit\fR if no wmbus devices are found, then exit immediately
|
||||
|
||||
\fB\--normal\fR for normal logging
|
||||
|
||||
\fB\--oneshot\fR wait for an update from each meter, then quit
|
||||
|
||||
\fB\--resetafter=\fR<time> reset the wmbus dongle regularly, default is 23h
|
||||
|
@ -210,6 +212,8 @@ device=im871a[12345678]:c1
|
|||
device=rtlwmbus:433M:c1,t1
|
||||
logtelegrams=false
|
||||
format=json
|
||||
# Remove meterfiles to spare precious flash memory when only
|
||||
# relaying data using for example mqtt.
|
||||
meterfiles=/var/log/wmbusmeters/meter_readings
|
||||
meterfilesaction=overwrite
|
||||
meterfilesnaming=name
|
||||
|
@ -220,7 +224,7 @@ alarmshell=/usr/bin/mosquitto_pub -h localhost -t wmbusmeters_alarm -m "$ALARM_T
|
|||
alarmtimeout=1h
|
||||
alarmexpectedactivity=mon-sun(00-23)
|
||||
ignoreduplicates=false
|
||||
json_address=MyStreet 5
|
||||
field_address=MyStreet 5
|
||||
.fi
|
||||
|
||||
.TP
|
||||
|
@ -231,13 +235,13 @@ name=MyTapWater
|
|||
type=multical21:c1
|
||||
id=12345678
|
||||
key=001122334455667788AABBCCDDEEFF
|
||||
json_floor=4
|
||||
field_floor=4
|
||||
|
||||
.SH AUTHOR
|
||||
Written by Fredrik Öhrström.
|
||||
|
||||
.SH COPYRIGHT
|
||||
Copyright \(co 2017-2020 Fredrik Öhrström.
|
||||
Copyright \(co 2017-2022 Fredrik Öhrström.
|
||||
.br
|
||||
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
|
||||
.br
|
||||
|
|
Ładowanie…
Reference in New Issue