Add support for Kelvin.

pull/451/head
Fredrik Öhrström 2022-01-13 15:06:53 +01:00
rodzic 14f5938401
commit 6af3b53d70
7 zmienionych plików z 41 dodań i 16 usunięć

Wyświetl plik

@ -506,7 +506,8 @@ bool extractDVdouble(map<string,pair<int,DVEntry>> *values,
string key,
int *offset,
double *value,
bool auto_scale)
bool auto_scale,
bool assume_signed)
{
if ((*values).count(key) == 0) {
verbose("(dvparser) warning: cannot extract double from non-existant key \"%s\"\n", key.c_str());
@ -538,21 +539,27 @@ bool extractDVdouble(map<string,pair<int,DVEntry>> *values,
vector<uchar> v;
hex2bin(p.second.value, &v);
uint64_t raw = 0;
bool negate = false;
uint64_t negate_mask = 0;
if (t == 0x1) {
assert(v.size() == 1);
raw = v[0];
if (assume_signed && (raw & (uint64_t)0x80UL) != 0) { negate = true; negate_mask = ~((uint64_t)0)<<8; }
} else if (t == 0x2) {
assert(v.size() == 2);
raw = v[1]*256 + v[0];
if (assume_signed && (raw & (uint64_t)0x8000UL) != 0) { negate = true; negate_mask = ~((uint64_t)0)<<16; }
} else if (t == 0x3) {
assert(v.size() == 3);
raw = v[2]*256*256 + v[1]*256 + v[0];
if (assume_signed && (raw & (uint64_t)0x800000UL) != 0) { negate = true; negate_mask = ~((uint64_t)0)<<24; }
} else if (t == 0x4) {
assert(v.size() == 4);
raw = ((unsigned int)v[3])*256*256*256
+ ((unsigned int)v[2])*256*256
+ ((unsigned int)v[1])*256
+ ((unsigned int)v[0]);
if (assume_signed && (raw & (uint64_t)0x80000000UL) != 0) { negate = true; negate_mask = ~((uint64_t)0)<<32; }
} else if (t == 0x6) {
assert(v.size() == 6);
raw = ((uint64_t)v[5])*256*256*256*256*256
@ -561,6 +568,7 @@ bool extractDVdouble(map<string,pair<int,DVEntry>> *values,
+ ((uint64_t)v[2])*256*256
+ ((uint64_t)v[1])*256
+ ((uint64_t)v[0]);
if (assume_signed && (raw & (uint64_t)0x800000000000UL) != 0) { negate = true; negate_mask = ~((uint64_t)0)<<48; }
} else if (t == 0x7) {
assert(v.size() == 8);
raw = ((uint64_t)v[7])*256*256*256*256*256*256*256
@ -571,10 +579,16 @@ bool extractDVdouble(map<string,pair<int,DVEntry>> *values,
+ ((uint64_t)v[2])*256*256
+ ((uint64_t)v[1])*256
+ ((uint64_t)v[0]);
if (assume_signed && (raw & (uint64_t)0x8000000000000000UL) != 0) { negate = true; negate_mask = 0; }
}
double scale = 1.0;
double draw = (double)raw;
if (negate)
{
draw = (double)((int64_t)(negate_mask | raw));
}
if (auto_scale) scale = vifScale(vif);
*value = ((double)raw) / scale;
*value = (draw) / scale;
}
else
if (t == 0x9 || // 2 digit BCD
@ -586,6 +600,8 @@ bool extractDVdouble(map<string,pair<int,DVEntry>> *values,
// 74140000 -> 00001474
string& v = p.second.value;
uint64_t raw = 0;
assert(assume_signed == false); // We do not expect negative bcd values.
// Even though it is theoretically possible with nines complement.
if (t == 0x9) {
assert(v.size() == 2);
raw = (v[0]-'0')*10 + (v[1]-'0');

Wyświetl plik

@ -1,5 +1,5 @@
/*
Copyright (C) 2018-2020 Fredrik Öhrström
Copyright (C) 2018-2022 Fredrik Öhrström
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
@ -153,10 +153,11 @@ bool extractDVuint32(std::map<std::string,std::pair<int,DVEntry>> *values,
// All values are scaled according to the vif and wmbusmeters scaling defaults.
bool extractDVdouble(std::map<std::string,std::pair<int,DVEntry>> *values,
std::string key,
int *offset,
double *value,
bool auto_scale = true);
std::string key,
int *offset,
double *value,
bool auto_scale = true,
bool assume_signed = false);
// Extract a value without scaling. Works for 8bits to 64 bits, binary and bcd.
bool extractDVlong(map<string,pair<int,DVEntry>> *values,

Wyświetl plik

@ -717,7 +717,10 @@ void MeterCommonImplementation::addFieldWithExtractor(
key,
&offset,
&extracted_double_value,
fi->vifScaling() == VifScaling::Auto))
fi->vifScaling() == VifScaling::Auto ||
fi->vifScaling() == VifScaling::AutoSigned,
fi->vifScaling() == VifScaling::NoneSigned ||
fi->vifScaling() == VifScaling::AutoSigned))
{
Unit decoded_unit = fi->defaultUnit();
if (fi->valueInformation() != ValueInformation::Any &&

Wyświetl plik

@ -271,8 +271,10 @@ vector<DriverInfo>& allRegisteredDrivers();
enum class VifScaling
{
None,
Auto
None, // No auto scaling.
Auto, // Scale to normalized VIF unit (ie kwh, m3, m3h etc)
NoneSigned, // No auto scaling however assume the value is signed.
AutoSigned // Scale and assume the value is signed.
};
struct FieldInfo

Wyświetl plik

@ -1,5 +1,5 @@
/*
Copyright (C) 2019-2020 Fredrik Öhrström
Copyright (C) 2019-2022 Fredrik Öhrström
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
@ -45,6 +45,8 @@ using namespace std;
X(M3H, LH, {vto=vfrom*1000.0;}) \
X(L, M3, {vto=vfrom/1000.0;}) \
X(LH, M3H,{vto=vfrom/1000.0;}) \
X(C, K, {vto=vfrom+273.15;}) \
X(K, C, {vto=vfrom-273.15;}) \
X(C, F, {vto=(vfrom*9.0/5.0)+32.0;}) \
X(F, C, {vto=(vfrom-32)*5.0/9.0;}) \

Wyświetl plik

@ -1,5 +1,5 @@
/*
Copyright (C) 2019-2020 Fredrik Öhrström
Copyright (C) 2019-2022 Fredrik Öhrström
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
@ -52,6 +52,7 @@
X(LH,lh,"l/h",Flow,"liters per hour") \
X(C,c,"°C",Temperature,"celsius") \
X(F,f,"°F",Temperature,"fahrenheit") \
X(K,k,"K",Temperature,"kelvin") \
X(RH,rh,"RH",RelativeHumidity,"relative humidity") \
X(HCA,hca,"hca",HCA,"heat cost allocation") \
X(TXT,txt,"txt",Text,"text") \

Wyświetl plik

@ -2421,10 +2421,10 @@ string vifType(int vif)
case 0x5E: return "Return temperature 10⁻¹ °C";
case 0x5F: return "Return temperature °C";
case 0x60: return "Temperature difference mK";
case 0x61: return "Temperature difference 10⁻² K";
case 0x62: return "Temperature difference 10⁻¹ K";
case 0x63: return "Temperature difference K";
case 0x60: return "Temperature difference mK or 10⁻³ °C?";
case 0x61: return "Temperature difference 10⁻² K or °C?";
case 0x62: return "Temperature difference 10⁻¹ K or °C?";
case 0x63: return "Temperature difference K or °C?";
case 0x64: return "External temperature 10⁻³ °C";
case 0x65: return "External temperature 10⁻² °C";