Fully converted driver ultraheat and values are stored based on vname()+xuantity().

pull/522/head
Fredrik Öhrström 2022-04-23 23:02:17 +02:00
rodzic 18466f9f2b
commit 61b9cd1df4
5 zmienionych plików z 102 dodań i 114 usunięć

Wyświetl plik

@ -17,121 +17,89 @@
#include"meters_common_implementation.h"
using namespace std;
struct MeterUltraHeat : public virtual MeterCommonImplementation
namespace
{
MeterUltraHeat(MeterInfo &mi, DriverInfo &di);
struct Driver : public virtual MeterCommonImplementation
{
Driver(MeterInfo &mi, DriverInfo &di);
};
private:
static bool ok = registerDriver([](DriverInfo&di)
{
di.setName("ultraheat");
di.setMeterType(MeterType::HeatMeter);
di.addDetection(MANUFACTURER_LUG, 0x04, 0x04);
di.setConstructor([](MeterInfo& mi, DriverInfo& di){ return shared_ptr<Meter>(new Driver(mi, di)); });
});
double heat_mj_ {};
double volume_m3_ {};
double power_kw_ {};
double flow_m3h_ {};
double flow_c_ {};
double return_c_ {};
};
Driver::Driver(MeterInfo &mi, DriverInfo &di) : MeterCommonImplementation(mi, di)
{
addNumericFieldWithExtractor(
"heat",
"The total heat energy consumption recorded by this meter.",
PrintProperty::JSON | PrintProperty::FIELD | PrintProperty::IMPORTANT,
Quantity::Energy,
VifScaling::Auto,
FieldMatcher::build()
.set(MeasurementType::Instantaneous)
.set(VIFRange::EnergyMJ)
);
static bool ok = registerDriver([](DriverInfo&di)
{
di.setName("ultraheat");
di.setMeterType(MeterType::HeatMeter);
di.addDetection(MANUFACTURER_LUG, 0x04, 0x04);
di.setConstructor([](MeterInfo& mi, DriverInfo& di){ return shared_ptr<Meter>(new MeterUltraHeat(mi, di)); });
});
addNumericFieldWithExtractor(
"volume",
"The total heating media volume recorded by this meter.",
PrintProperty::JSON,
Quantity::Volume,
VifScaling::Auto,
FieldMatcher::build()
.set(MeasurementType::Instantaneous)
.set(VIFRange::Volume)
);
MeterUltraHeat::MeterUltraHeat(MeterInfo &mi, DriverInfo &di) : MeterCommonImplementation(mi, di)
{
addNumericFieldWithExtractor(
"heat",
Quantity::Energy,
NoDifVifKey,
VifScaling::Auto,
MeasurementType::Instantaneous,
VIFRange::EnergyMJ,
StorageNr(0),
TariffNr(0),
IndexNr(1),
PrintProperty::JSON | PrintProperty::FIELD | PrintProperty::IMPORTANT,
"The total heat energy consumption recorded by this meter.",
SET_FUNC(heat_mj_, Unit::MJ),
GET_FUNC(heat_mj_, Unit::MJ));
addNumericFieldWithExtractor(
"power",
"The current power consumption.",
PrintProperty::JSON ,
Quantity::Power,
VifScaling::Auto,
FieldMatcher::build()
.set(MeasurementType::Instantaneous)
.set(VIFRange::PowerW)
);
addNumericFieldWithExtractor(
"volume",
Quantity::Volume,
NoDifVifKey,
VifScaling::Auto,
MeasurementType::Instantaneous,
VIFRange::Volume,
StorageNr(0),
TariffNr(0),
IndexNr(1),
PrintProperty::JSON ,
"The total heating media volume recorded by this meter.",
SET_FUNC(volume_m3_, Unit::M3),
GET_FUNC(volume_m3_, Unit::M3));
addNumericFieldWithExtractor(
"flow",
"The current heat media volume flow.",
PrintProperty::JSON ,
Quantity::Flow,
VifScaling::Auto,
FieldMatcher::build()
.set(MeasurementType::Instantaneous)
.set(VIFRange::VolumeFlow)
);
addNumericFieldWithExtractor(
"power",
Quantity::Power,
NoDifVifKey,
VifScaling::Auto,
MeasurementType::Instantaneous,
VIFRange::PowerW,
StorageNr(0),
TariffNr(0),
IndexNr(1),
PrintProperty::JSON ,
"The current power consumption.",
SET_FUNC(power_kw_, Unit::KW),
GET_FUNC(power_kw_, Unit::KW));
addNumericFieldWithExtractor(
"flow",
"The current forward heat media temperature.",
PrintProperty::JSON ,
Quantity::Temperature,
VifScaling::Auto,
FieldMatcher::build()
.set(MeasurementType::Instantaneous)
.set(VIFRange::FlowTemperature)
);
addNumericFieldWithExtractor(
"flow",
Quantity::Flow,
NoDifVifKey,
VifScaling::Auto,
MeasurementType::Instantaneous,
VIFRange::VolumeFlow,
StorageNr(0),
TariffNr(0),
IndexNr(1),
PrintProperty::JSON ,
"The current heat media volume flow.",
SET_FUNC(flow_m3h_, Unit::M3H),
GET_FUNC(flow_m3h_, Unit::M3H));
addNumericFieldWithExtractor(
"flow",
Quantity::Temperature,
NoDifVifKey,
VifScaling::Auto,
MeasurementType::Instantaneous,
VIFRange::FlowTemperature,
StorageNr(0),
TariffNr(0),
IndexNr(1),
PrintProperty::JSON ,
"The current forward heat media temperature.",
SET_FUNC(flow_c_, Unit::C),
GET_FUNC(flow_c_, Unit::C));
addNumericFieldWithExtractor(
"return",
Quantity::Temperature,
NoDifVifKey,
VifScaling::Auto,
MeasurementType::Instantaneous,
VIFRange::ReturnTemperature,
StorageNr(0),
TariffNr(0),
IndexNr(1),
PrintProperty::JSON ,
"The current return heat media temperature.",
SET_FUNC(return_c_, Unit::C),
GET_FUNC(return_c_, Unit::C));
addNumericFieldWithExtractor(
"return",
"The current return heat media temperature.",
PrintProperty::JSON ,
Quantity::Temperature,
VifScaling::Auto,
FieldMatcher::build()
.set(MeasurementType::Instantaneous)
.set(VIFRange::ReturnTemperature)
);
}
}
// Test: MyUltra ultraheat 70444600 NOKEY

Wyświetl plik

@ -1509,7 +1509,11 @@ void MeterCommonImplementation::processFieldExtractors(Telegram *t)
{
if (fi.hasMatcher() && fi.matches(dve))
{
debug("Using field info %s to extract %d\n", fi.vname().c_str(), dve->dif_vif_key.str().c_str());
debug("(meters) using field info %s(%s)[%d] to extract %s\n",
fi.vname().c_str(),
toString(fi.xuantity()),
fi.index(),
dve->dif_vif_key.str().c_str());
dve->setFieldInfo(&fi);
fi.performExtraction(this, t, dve);
}
@ -1540,7 +1544,7 @@ void MeterCommonImplementation::setNumericValue(FieldInfo *fi, Unit u, double v)
// Store value in default meter location for numeric values.
string field_name_no_unit = fi->vname();
numeric_values_[field_name_no_unit] = NumericField(u, v, fi);
numeric_values_[pair<string,Quantity>(field_name_no_unit,fi->xuantity())] = NumericField(u, v, fi);
}
double MeterCommonImplementation::getNumericValue(FieldInfo *fi, Unit to)
@ -1551,11 +1555,12 @@ double MeterCommonImplementation::getNumericValue(FieldInfo *fi, Unit to)
}
string field_name_no_unit = fi->vname();
if (numeric_values_.count(field_name_no_unit) == 0)
pair<string,Quantity> key(field_name_no_unit,fi->xuantity());
if (numeric_values_.count(key) == 0)
{
return std::numeric_limits<double>::quiet_NaN(); // This is translated into a null in the json.
}
NumericField &nf = numeric_values_[field_name_no_unit];
NumericField &nf = numeric_values_[key];
return convert(nf.value, nf.unit, to);
}
@ -1738,7 +1743,14 @@ void MeterCommonImplementation::printMeter(Telegram *t,
// Has the entry been matches to this field, then print it as json.
if (dve->getFieldInfo() == &fi)
{
s += indent+fi.renderJson(this, &conversions())+","+newline;
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,
dve->dif_vif_key.str().c_str(),
dve->value.c_str());
string out = fi.renderJson(this, &conversions());
debug("(meters) %s\n", out.c_str());
s += indent+out+","+newline;
found = true;
}
}

Wyświetl plik

@ -244,7 +244,7 @@ protected:
// Map difvif key to hex values from telegrams.
std::map<std::string,std::pair<int,std::string>> hex_values_;
// Map field name (total_volume) to numeric value.
std::map<std::string,NumericField> numeric_values_;
std::map<pair<std::string,Quantity>,NumericField> numeric_values_;
// Map field name (at_date) to string value.
std::map<std::string,StringField> string_values_;
};

Wyświetl plik

@ -74,7 +74,7 @@ LIST_OF_CONVERSIONS
string from = unitToStringHR(ufrom);
string to = unitToStringHR(uto);
fprintf(stderr, "Cannot convert between units! %s %s\n", from.c_str(), to.c_str());
fprintf(stderr, "Cannot convert between units! from %s to %s\n", from.c_str(), to.c_str());
assert(0);
return 0;
}
@ -105,6 +105,13 @@ LIST_OF_QUANTITIES
return Unit::Unknown;
}
const char *toString(Quantity q)
{
#define X(quantity,default_unit) if (q == Quantity::quantity) return #quantity;
LIST_OF_QUANTITIES
#undef X
return "?";
}
Unit toUnit(string s)
{

Wyświetl plik

@ -88,6 +88,7 @@ LIST_OF_QUANTITIES
bool canConvert(Unit from, Unit to);
double convert(double v, Unit from, Unit to);
Unit toUnit(std::string s);
const char *toString(Quantity q);
bool isQuantity(Unit u, Quantity q);
void assertQuantity(Unit u, Quantity q);
Unit defaultUnitForQuantity(Quantity q);