Improve BCD decoding (#167)
* Introduce mbus_data_bcd_decode_hex The convert function mbus_data_bcd_decode (BCD to decimal) suffers from information loss in case of hexacimal digits. So introduce a new function mbus_data_bcd_decode_hex (BCD to hexadecimal), which isn't affected and use this for default XML output. But keep mbus_data_bcd_decode for normalized output.
This commit is contained in:
parent
1e25cf1096
commit
17a73287c2
@ -490,7 +490,7 @@ mbus_data_bcd_encode(unsigned char *bcd_data, size_t bcd_data_size, int value)
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
///
|
||||
/// Decode BCD data
|
||||
/// Decode BCD data (decimal)
|
||||
///
|
||||
//------------------------------------------------------------------------------
|
||||
long long
|
||||
@ -525,6 +525,30 @@ mbus_data_bcd_decode(unsigned char *bcd_data, size_t bcd_data_size)
|
||||
return -1;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
///
|
||||
/// Decode BCD data (hexadecimal)
|
||||
///
|
||||
//------------------------------------------------------------------------------
|
||||
long long
|
||||
mbus_data_bcd_decode_hex(unsigned char *bcd_data, size_t bcd_data_size)
|
||||
{
|
||||
long long val = 0;
|
||||
size_t i;
|
||||
|
||||
if (bcd_data)
|
||||
{
|
||||
for (i = bcd_data_size; i > 0; i--)
|
||||
{
|
||||
val = (val << 8) | bcd_data[i-1];
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
///
|
||||
/// Decode INTEGER data
|
||||
@ -2730,8 +2754,8 @@ mbus_data_record_decode(mbus_data_record *record)
|
||||
|
||||
case 0x09: // 2 digit BCD (8 bit)
|
||||
|
||||
int_val = (int)mbus_data_bcd_decode(record->data, 1);
|
||||
snprintf(buff, sizeof(buff), "%d", int_val);
|
||||
int_val = (int)mbus_data_bcd_decode_hex(record->data, 1);
|
||||
snprintf(buff, sizeof(buff), "%X", int_val);
|
||||
|
||||
if (debug)
|
||||
printf("%s: DIF 0x%.2x was decoded using 2 digit BCD\n", __PRETTY_FUNCTION__, record->drh.dib.dif);
|
||||
@ -2740,8 +2764,8 @@ mbus_data_record_decode(mbus_data_record *record)
|
||||
|
||||
case 0x0A: // 4 digit BCD (16 bit)
|
||||
|
||||
int_val = (int)mbus_data_bcd_decode(record->data, 2);
|
||||
snprintf(buff, sizeof(buff), "%d", int_val);
|
||||
int_val = (int)mbus_data_bcd_decode_hex(record->data, 2);
|
||||
snprintf(buff, sizeof(buff), "%X", int_val);
|
||||
|
||||
if (debug)
|
||||
printf("%s: DIF 0x%.2x was decoded using 4 digit BCD\n", __PRETTY_FUNCTION__, record->drh.dib.dif);
|
||||
@ -2750,8 +2774,8 @@ mbus_data_record_decode(mbus_data_record *record)
|
||||
|
||||
case 0x0B: // 6 digit BCD (24 bit)
|
||||
|
||||
int_val = (int)mbus_data_bcd_decode(record->data, 3);
|
||||
snprintf(buff, sizeof(buff), "%d", int_val);
|
||||
int_val = (int)mbus_data_bcd_decode_hex(record->data, 3);
|
||||
snprintf(buff, sizeof(buff), "%X", int_val);
|
||||
|
||||
if (debug)
|
||||
printf("%s: DIF 0x%.2x was decoded using 6 digit BCD\n", __PRETTY_FUNCTION__, record->drh.dib.dif);
|
||||
@ -2760,8 +2784,8 @@ mbus_data_record_decode(mbus_data_record *record)
|
||||
|
||||
case 0x0C: // 8 digit BCD (32 bit)
|
||||
|
||||
int_val = (int)mbus_data_bcd_decode(record->data, 4);
|
||||
snprintf(buff, sizeof(buff), "%d", int_val);
|
||||
int_val = (int)mbus_data_bcd_decode_hex(record->data, 4);
|
||||
snprintf(buff, sizeof(buff), "%X", int_val);
|
||||
|
||||
if (debug)
|
||||
printf("%s: DIF 0x%.2x was decoded using 8 digit BCD\n", __PRETTY_FUNCTION__, record->drh.dib.dif);
|
||||
@ -2770,8 +2794,8 @@ mbus_data_record_decode(mbus_data_record *record)
|
||||
|
||||
case 0x0E: // 12 digit BCD (48 bit)
|
||||
|
||||
long_long_val = mbus_data_bcd_decode(record->data, 6);
|
||||
snprintf(buff, sizeof(buff), "%lld", long_long_val);
|
||||
long_long_val = mbus_data_bcd_decode_hex(record->data, 6);
|
||||
snprintf(buff, sizeof(buff), "%llX", long_long_val);
|
||||
|
||||
if (debug)
|
||||
printf("%s: DIF 0x%.2x was decoded using 12 digit BCD\n", __PRETTY_FUNCTION__, record->drh.dib.dif);
|
||||
@ -3761,8 +3785,8 @@ mbus_data_variable_header_print(mbus_data_variable_header *header)
|
||||
{
|
||||
if (header)
|
||||
{
|
||||
printf("%s: ID = %lld\n", __PRETTY_FUNCTION__,
|
||||
mbus_data_bcd_decode(header->id_bcd, 4));
|
||||
printf("%s: ID = %llX\n", __PRETTY_FUNCTION__,
|
||||
mbus_data_bcd_decode_hex(header->id_bcd, 4));
|
||||
|
||||
printf("%s: Manufacturer = 0x%.2X%.2X\n", __PRETTY_FUNCTION__,
|
||||
header->manufacturer[1], header->manufacturer[0]);
|
||||
@ -3863,7 +3887,7 @@ mbus_data_fixed_print(mbus_data_fixed *data)
|
||||
|
||||
if (data)
|
||||
{
|
||||
printf("%s: ID = %lld\n", __PRETTY_FUNCTION__, mbus_data_bcd_decode(data->id_bcd, 4));
|
||||
printf("%s: ID = %llX\n", __PRETTY_FUNCTION__, mbus_data_bcd_decode_hex(data->id_bcd, 4));
|
||||
printf("%s: Access # = 0x%.2X\n", __PRETTY_FUNCTION__, data->tx_cnt);
|
||||
printf("%s: Status = 0x%.2X\n", __PRETTY_FUNCTION__, data->status);
|
||||
printf("%s: Function = %s\n", __PRETTY_FUNCTION__, mbus_data_fixed_function(data->status));
|
||||
@ -3872,7 +3896,7 @@ mbus_data_fixed_print(mbus_data_fixed *data)
|
||||
printf("%s: Unit1 = %s\n", __PRETTY_FUNCTION__, mbus_data_fixed_unit(data->cnt1_type));
|
||||
if ((data->status & MBUS_DATA_FIXED_STATUS_FORMAT_MASK) == MBUS_DATA_FIXED_STATUS_FORMAT_BCD)
|
||||
{
|
||||
printf("%s: Counter1 = %lld\n", __PRETTY_FUNCTION__, mbus_data_bcd_decode(data->cnt1_val, 4));
|
||||
printf("%s: Counter1 = %llX\n", __PRETTY_FUNCTION__, mbus_data_bcd_decode_hex(data->cnt1_val, 4));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -3884,7 +3908,7 @@ mbus_data_fixed_print(mbus_data_fixed *data)
|
||||
printf("%s: Unit2 = %s\n", __PRETTY_FUNCTION__, mbus_data_fixed_unit(data->cnt2_type));
|
||||
if ((data->status & MBUS_DATA_FIXED_STATUS_FORMAT_MASK) == MBUS_DATA_FIXED_STATUS_FORMAT_BCD)
|
||||
{
|
||||
printf("%s: Counter2 = %lld\n", __PRETTY_FUNCTION__, mbus_data_bcd_decode(data->cnt2_val, 4));
|
||||
printf("%s: Counter2 = %llX\n", __PRETTY_FUNCTION__, mbus_data_bcd_decode_hex(data->cnt2_val, 4));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -4015,7 +4039,7 @@ mbus_data_variable_header_xml(mbus_data_variable_header *header)
|
||||
{
|
||||
len += snprintf(&buff[len], sizeof(buff) - len, " <SlaveInformation>\n");
|
||||
|
||||
len += snprintf(&buff[len], sizeof(buff) - len, " <Id>%lld</Id>\n", mbus_data_bcd_decode(header->id_bcd, 4));
|
||||
len += snprintf(&buff[len], sizeof(buff) - len, " <Id>%llX</Id>\n", mbus_data_bcd_decode_hex(header->id_bcd, 4));
|
||||
len += snprintf(&buff[len], sizeof(buff) - len, " <Manufacturer>%s</Manufacturer>\n",
|
||||
mbus_decode_manufacturer(header->manufacturer[0], header->manufacturer[1]));
|
||||
len += snprintf(&buff[len], sizeof(buff) - len, " <Version>%d</Version>\n", header->version);
|
||||
@ -4193,7 +4217,7 @@ mbus_data_fixed_xml(mbus_data_fixed *data)
|
||||
len += snprintf(&buff[len], buff_size - len, "<MBusData>\n\n");
|
||||
|
||||
len += snprintf(&buff[len], buff_size - len, " <SlaveInformation>\n");
|
||||
len += snprintf(&buff[len], buff_size - len, " <Id>%lld</Id>\n", mbus_data_bcd_decode(data->id_bcd, 4));
|
||||
len += snprintf(&buff[len], buff_size - len, " <Id>%llX</Id>\n", mbus_data_bcd_decode_hex(data->id_bcd, 4));
|
||||
|
||||
mbus_str_xml_encode(str_encoded, mbus_data_fixed_medium(data), sizeof(str_encoded));
|
||||
len += snprintf(&buff[len], buff_size - len, " <Medium>%s</Medium>\n", str_encoded);
|
||||
@ -4211,7 +4235,7 @@ mbus_data_fixed_xml(mbus_data_fixed *data)
|
||||
len += snprintf(&buff[len], buff_size - len, " <Unit>%s</Unit>\n", str_encoded);
|
||||
if ((data->status & MBUS_DATA_FIXED_STATUS_FORMAT_MASK) == MBUS_DATA_FIXED_STATUS_FORMAT_BCD)
|
||||
{
|
||||
len += snprintf(&buff[len], buff_size - len, " <Value>%lld</Value>\n", mbus_data_bcd_decode(data->cnt1_val, 4));
|
||||
len += snprintf(&buff[len], buff_size - len, " <Value>%llX</Value>\n", mbus_data_bcd_decode_hex(data->cnt1_val, 4));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -4230,7 +4254,7 @@ mbus_data_fixed_xml(mbus_data_fixed *data)
|
||||
len += snprintf(&buff[len], buff_size - len, " <Unit>%s</Unit>\n", str_encoded);
|
||||
if ((data->status & MBUS_DATA_FIXED_STATUS_FORMAT_MASK) == MBUS_DATA_FIXED_STATUS_FORMAT_BCD)
|
||||
{
|
||||
len += snprintf(&buff[len], buff_size - len, " <Value>%lld</Value>\n", mbus_data_bcd_decode(data->cnt2_val, 4));
|
||||
len += snprintf(&buff[len], buff_size - len, " <Value>%llX</Value>\n", mbus_data_bcd_decode_hex(data->cnt2_val, 4));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -4589,9 +4613,9 @@ mbus_frame_get_secondary_address(mbus_frame *frame)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
id = (unsigned long) mbus_data_bcd_decode(data->data_var.header.id_bcd, 4);
|
||||
id = (unsigned long) mbus_data_bcd_decode_hex(data->data_var.header.id_bcd, 4);
|
||||
|
||||
snprintf(addr, sizeof(addr), "%08lu%02X%02X%02X%02X",
|
||||
snprintf(addr, sizeof(addr), "%08lX%02X%02X%02X%02X",
|
||||
id,
|
||||
data->data_var.header.manufacturer[0],
|
||||
data->data_var.header.manufacturer[1],
|
||||
|
@ -627,6 +627,7 @@ int mbus_data_bcd_encode(unsigned char *bcd_data, size_t bcd_data_size, int valu
|
||||
int mbus_data_int_encode(unsigned char *int_data, size_t int_data_size, int value);
|
||||
|
||||
long long mbus_data_bcd_decode(unsigned char *bcd_data, size_t bcd_data_size);
|
||||
long long mbus_data_bcd_decode_hex(unsigned char *bcd_data, size_t bcd_data_size);
|
||||
int mbus_data_int_decode(unsigned char *int_data, size_t int_data_size, int *value);
|
||||
int mbus_data_long_decode(unsigned char *int_data, size_t int_data_size, long *value);
|
||||
int mbus_data_long_long_decode(unsigned char *int_data, size_t int_data_size, long long *value);
|
||||
|
@ -6,7 +6,7 @@
|
||||
<Manufacturer>EFE</Manufacturer>
|
||||
<Version>0</Version>
|
||||
<ProductName>Engelmann WaterStar</ProductName>
|
||||
<Medium>Hot water</Medium>
|
||||
<Medium>Warm water (30-90°C)</Medium>
|
||||
<AccessNumber>12</AccessNumber>
|
||||
<Status>27</Status>
|
||||
<Signature>0000</Signature>
|
||||
|
@ -48,14 +48,14 @@
|
||||
<Function>Value during error state</Function>
|
||||
<StorageNumber>0</StorageNumber>
|
||||
<Unit>Power (W)</Unit>
|
||||
<Value>144445223</Value>
|
||||
<Value>DDDDEBBD</Value>
|
||||
</DataRecord>
|
||||
|
||||
<DataRecord id="5">
|
||||
<Function>Value during error state</Function>
|
||||
<StorageNumber>0</StorageNumber>
|
||||
<Unit>Volume flow (m m^3/h)</Unit>
|
||||
<Value>1445223</Value>
|
||||
<Value>DDEBBD</Value>
|
||||
</DataRecord>
|
||||
|
||||
<DataRecord id="6">
|
||||
|
@ -58,7 +58,7 @@
|
||||
<Function>Instantaneous value</Function>
|
||||
<StorageNumber>0</StorageNumber>
|
||||
<Unit>Temperature Difference (1e-2 deg C)</Unit>
|
||||
<Value>1500018</Value>
|
||||
<Value>F00018</Value>
|
||||
</DataRecord>
|
||||
|
||||
<DataRecord id="7">
|
||||
|
@ -30,14 +30,14 @@
|
||||
<Function>Value during error state</Function>
|
||||
<StorageNumber>0</StorageNumber>
|
||||
<Unit>Power (1e-1 W)</Unit>
|
||||
<Value>144521543</Value>
|
||||
<Value>DDEBB4DD</Value>
|
||||
</DataRecord>
|
||||
|
||||
<DataRecord id="3">
|
||||
<Function>Value during error state</Function>
|
||||
<StorageNumber>0</StorageNumber>
|
||||
<Unit>Volume flow (1e-4 m^3/h)</Unit>
|
||||
<Value>1521543</Value>
|
||||
<Value>EBB4DD</Value>
|
||||
</DataRecord>
|
||||
|
||||
<DataRecord id="4">
|
||||
|
@ -2,7 +2,7 @@
|
||||
<MBusData>
|
||||
|
||||
<SlaveInformation>
|
||||
<Id>5000244</Id>
|
||||
<Id>500023E</Id>
|
||||
<Manufacturer>SBC</Manufacturer>
|
||||
<Version>18</Version>
|
||||
<ProductName></ProductName>
|
||||
|
@ -2,7 +2,7 @@
|
||||
<MBusData>
|
||||
|
||||
<SlaveInformation>
|
||||
<Id>5000345</Id>
|
||||
<Id>50002E5</Id>
|
||||
<Manufacturer>@@@</Manufacturer>
|
||||
<Version>18</Version>
|
||||
<ProductName></ProductName>
|
||||
|
@ -72,7 +72,7 @@
|
||||
<Function>Instantaneous value</Function>
|
||||
<StorageNumber>0</StorageNumber>
|
||||
<Unit>Temperature Difference (1e-1 deg C)</Unit>
|
||||
<Value>1500002</Value>
|
||||
<Value>F00002</Value>
|
||||
</DataRecord>
|
||||
|
||||
<DataRecord id="9">
|
||||
|
@ -6,7 +6,7 @@
|
||||
<Manufacturer>LSE</Manufacturer>
|
||||
<Version>153</Version>
|
||||
<ProductName>Siemens WFH21</ProductName>
|
||||
<Medium>Hot water</Medium>
|
||||
<Medium>Warm water (30-90°C)</Medium>
|
||||
<AccessNumber>235</AccessNumber>
|
||||
<Status>00</Status>
|
||||
<Signature>0000</Signature>
|
||||
|
@ -6,7 +6,7 @@
|
||||
<Manufacturer>LSE</Manufacturer>
|
||||
<Version>153</Version>
|
||||
<ProductName>Siemens WFH21</ProductName>
|
||||
<Medium>Hot water</Medium>
|
||||
<Medium>Warm water (30-90°C)</Medium>
|
||||
<AccessNumber>218</AccessNumber>
|
||||
<Status>00</Status>
|
||||
<Signature>0000</Signature>
|
||||
|
Loading…
x
Reference in New Issue
Block a user