Merge pull request #111 from lategoodbye/upstream-cp48
Implement type I CP48 (date and time)
This commit is contained in:
@ -878,7 +878,7 @@ int mbus_variable_value_decode(mbus_data_record *record, double *value_out_real,
|
||||
return -1;
|
||||
}
|
||||
*value_out_str_size = snprintf(*value_out_str, 11, "%04d-%02d-%02d",
|
||||
(time.tm_year + 2000),
|
||||
(time.tm_year + 1900),
|
||||
(time.tm_mon + 1),
|
||||
time.tm_mday);
|
||||
result = 0;
|
||||
@ -910,7 +910,7 @@ int mbus_variable_value_decode(mbus_data_record *record, double *value_out_real,
|
||||
return -1;
|
||||
}
|
||||
*value_out_str_size = snprintf(*value_out_str, 20, "%04d-%02d-%02dT%02d:%02d:%02d",
|
||||
(time.tm_year + 2000),
|
||||
(time.tm_year + 1900),
|
||||
(time.tm_mon + 1),
|
||||
time.tm_mday,
|
||||
time.tm_hour,
|
||||
@ -931,8 +931,33 @@ int mbus_variable_value_decode(mbus_data_record *record, double *value_out_real,
|
||||
break;
|
||||
|
||||
case 0x06: /* 6 byte integer (48 bit) */
|
||||
result = mbus_data_long_long_decode(record->data, 6, &value_out_long_long);
|
||||
*value_out_real = value_out_long_long;
|
||||
// E110 1101 Time Point (date/time)
|
||||
// E011 0000 Start (date/time) of tariff
|
||||
// E111 0000 Date and time of battery change
|
||||
if ( (vif == 0x6D) ||
|
||||
((record->drh.vib.vif == 0xFD) && (vife == 0x30)) ||
|
||||
((record->drh.vib.vif == 0xFD) && (vife == 0x70)))
|
||||
{
|
||||
mbus_data_tm_decode(&time, record->data, 6);
|
||||
if ((*value_out_str = (char*) malloc(20)) == NULL)
|
||||
{
|
||||
MBUS_ERROR("Unable to allocate memory");
|
||||
return -1;
|
||||
}
|
||||
*value_out_str_size = snprintf(*value_out_str, 20, "%04d-%02d-%02dT%02d:%02d:%02d",
|
||||
(time.tm_year + 1900),
|
||||
(time.tm_mon + 1),
|
||||
time.tm_mday,
|
||||
time.tm_hour,
|
||||
time.tm_min,
|
||||
time.tm_sec);
|
||||
result = 0;
|
||||
}
|
||||
else // normal integer
|
||||
{
|
||||
result = mbus_data_long_long_decode(record->data, 6, &value_out_long_long);
|
||||
*value_out_real = value_out_long_long;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x07: /* 8 byte integer (64 bit) */
|
||||
|
@ -750,7 +750,15 @@ mbus_data_bin_decode(unsigned char *dst, const unsigned char *src, size_t len, s
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
///
|
||||
/// Decode time data (usable for type f = 4 bytes or type g = 2 bytes)
|
||||
/// Decode time data
|
||||
///
|
||||
/// Usable for the following types:
|
||||
/// I = 6 bytes (Date and time)
|
||||
/// F = 4 bytes (Date and time)
|
||||
/// G = 2 bytes (Date)
|
||||
///
|
||||
/// TODO:
|
||||
/// J = 3 bytes (Time)
|
||||
///
|
||||
//------------------------------------------------------------------------------
|
||||
void
|
||||
@ -773,7 +781,21 @@ mbus_data_tm_decode(struct tm *t, unsigned char *t_data, size_t t_data_size)
|
||||
|
||||
if (t_data)
|
||||
{
|
||||
if (t_data_size == 4) // Type F = Compound CP32: Date and Time
|
||||
if (t_data_size == 6) // Type I = Compound CP48: Date and Time
|
||||
{
|
||||
if ((t_data[1] & 0x80) == 0) // Time valid ?
|
||||
{
|
||||
t->tm_sec = t_data[0] & 0x3F;
|
||||
t->tm_min = t_data[1] & 0x3F;
|
||||
t->tm_hour = t_data[2] & 0x1F;
|
||||
t->tm_mday = t_data[3] & 0x1F;
|
||||
t->tm_mon = (t_data[4] & 0x0F) - 1;
|
||||
t->tm_year = 100 + (((t_data[3] & 0xE0) >> 5) |
|
||||
((t_data[4] & 0xF0) >> 1));
|
||||
t->tm_isdst = (t_data[0] & 0x40) ? 1 : 0; // day saving time
|
||||
}
|
||||
}
|
||||
else if (t_data_size == 4) // Type F = Compound CP32: Date and Time
|
||||
{
|
||||
if ((t_data[0] & 0x80) == 0) // Time valid ?
|
||||
{
|
||||
@ -781,8 +803,8 @@ mbus_data_tm_decode(struct tm *t, unsigned char *t_data, size_t t_data_size)
|
||||
t->tm_hour = t_data[1] & 0x1F;
|
||||
t->tm_mday = t_data[2] & 0x1F;
|
||||
t->tm_mon = (t_data[3] & 0x0F) - 1;
|
||||
t->tm_year = ((t_data[2] & 0xE0) >> 5) |
|
||||
((t_data[3] & 0xF0) >> 1);
|
||||
t->tm_year = 100 + (((t_data[2] & 0xE0) >> 5) |
|
||||
((t_data[3] & 0xF0) >> 1));
|
||||
t->tm_isdst = (t_data[1] & 0x80) ? 1 : 0; // day saving time
|
||||
}
|
||||
}
|
||||
@ -790,8 +812,8 @@ mbus_data_tm_decode(struct tm *t, unsigned char *t_data, size_t t_data_size)
|
||||
{
|
||||
t->tm_mday = t_data[0] & 0x1F;
|
||||
t->tm_mon = (t_data[1] & 0x0F) - 1;
|
||||
t->tm_year = ((t_data[0] & 0xE0) >> 5) |
|
||||
((t_data[1] & 0xF0) >> 1);
|
||||
t->tm_year = 100 + (((t_data[0] & 0xE0) >> 5) |
|
||||
((t_data[1] & 0xF0) >> 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2436,7 +2458,7 @@ mbus_data_record_decode(mbus_data_record *record)
|
||||
{
|
||||
mbus_data_tm_decode(&time, record->data, 2);
|
||||
snprintf(buff, sizeof(buff), "%04d-%02d-%02d",
|
||||
(time.tm_year + 2000),
|
||||
(time.tm_year + 1900),
|
||||
(time.tm_mon + 1),
|
||||
time.tm_mday);
|
||||
}
|
||||
@ -2473,7 +2495,7 @@ mbus_data_record_decode(mbus_data_record *record)
|
||||
{
|
||||
mbus_data_tm_decode(&time, record->data, 4);
|
||||
snprintf(buff, sizeof(buff), "%04d-%02d-%02dT%02d:%02d:%02d",
|
||||
(time.tm_year + 2000),
|
||||
(time.tm_year + 1900),
|
||||
(time.tm_mon + 1),
|
||||
time.tm_mday,
|
||||
time.tm_hour,
|
||||
@ -2502,11 +2524,29 @@ mbus_data_record_decode(mbus_data_record *record)
|
||||
|
||||
break;
|
||||
|
||||
case 0x06: // 6 byte integer (48 bit)
|
||||
case 0x06: // 6 byte (48 bit)
|
||||
|
||||
mbus_data_long_long_decode(record->data, 6, &long_long_val);
|
||||
|
||||
snprintf(buff, sizeof(buff), "%lld", long_long_val);
|
||||
// E110 1101 Time Point (date/time)
|
||||
// E011 0000 Start (date/time) of tariff
|
||||
// E111 0000 Date and time of battery change
|
||||
if ( (vif == 0x6D) ||
|
||||
((record->drh.vib.vif == 0xFD) && (vife == 0x30)) ||
|
||||
((record->drh.vib.vif == 0xFD) && (vife == 0x70)))
|
||||
{
|
||||
mbus_data_tm_decode(&time, record->data, 6);
|
||||
snprintf(buff, sizeof(buff), "%04d-%02d-%02dT%02d:%02d:%02d",
|
||||
(time.tm_year + 1900),
|
||||
(time.tm_mon + 1),
|
||||
time.tm_mday,
|
||||
time.tm_hour,
|
||||
time.tm_min,
|
||||
time.tm_sec);
|
||||
}
|
||||
else // 6 byte integer
|
||||
{
|
||||
mbus_data_long_long_decode(record->data, 6, &long_long_val);
|
||||
snprintf(buff, sizeof(buff), "%lld", long_long_val);
|
||||
}
|
||||
|
||||
if (debug)
|
||||
printf("%s: DIF 0x%.2x was decoded using 6 byte integer\n", __PRETTY_FUNCTION__, record->drh.dib.dif);
|
||||
|
1
test/test-frames/LGB_G350.hex
Normal file
1
test/test-frames/LGB_G350.hex
Normal file
@ -0,0 +1 @@
|
||||
68 40 40 68 08 01 72 58 20 08 12 E2 30 40 03 40 00 00 00 2F 2F 4C 13 92 40 83 10 46 6D 00 00 08 16 27 00 0D 78 11 34 31 38 35 30 32 38 30 32 31 39 35 37 31 30 30 47 89 40 FD 1A 01 01 FD 17 00 01 FD 67 0F 38 16
|
59
test/test-frames/LGB_G350.xml
Normal file
59
test/test-frames/LGB_G350.xml
Normal file
@ -0,0 +1,59 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<MBusData>
|
||||
|
||||
<SlaveInformation>
|
||||
<Id>12082058</Id>
|
||||
<Manufacturer>LGB</Manufacturer>
|
||||
<Version>64</Version>
|
||||
<ProductName></ProductName>
|
||||
<Medium>Gas</Medium>
|
||||
<AccessNumber>64</AccessNumber>
|
||||
<Status>00</Status>
|
||||
<Signature>0000</Signature>
|
||||
</SlaveInformation>
|
||||
|
||||
<DataRecord id="0">
|
||||
<Function>Instantaneous value</Function>
|
||||
<StorageNumber>1</StorageNumber>
|
||||
<Unit>Volume (m m^3)</Unit>
|
||||
<Value>10834092</Value>
|
||||
</DataRecord>
|
||||
|
||||
<DataRecord id="1">
|
||||
<Function>Instantaneous value</Function>
|
||||
<StorageNumber>1</StorageNumber>
|
||||
<Unit>Time Point (time & date)</Unit>
|
||||
<Value>2016-07-22T08:00:00</Value>
|
||||
</DataRecord>
|
||||
|
||||
<DataRecord id="2">
|
||||
<Function>Instantaneous value</Function>
|
||||
<StorageNumber>0</StorageNumber>
|
||||
<Unit>Fabrication number</Unit>
|
||||
<Value>G0017591208205814</Value>
|
||||
</DataRecord>
|
||||
|
||||
<DataRecord id="3">
|
||||
<Function>Instantaneous value</Function>
|
||||
<StorageNumber>0</StorageNumber>
|
||||
<Tariff>0</Tariff>
|
||||
<Device>1</Device>
|
||||
<Unit>Digital output (binary)</Unit>
|
||||
<Value>1</Value>
|
||||
</DataRecord>
|
||||
|
||||
<DataRecord id="4">
|
||||
<Function>Instantaneous value</Function>
|
||||
<StorageNumber>0</StorageNumber>
|
||||
<Unit>Error flags</Unit>
|
||||
<Value>0</Value>
|
||||
</DataRecord>
|
||||
|
||||
<DataRecord id="5">
|
||||
<Function>Instantaneous value</Function>
|
||||
<StorageNumber>0</StorageNumber>
|
||||
<Unit>Unrecognized VIF extension: 0x67</Unit>
|
||||
<Value>15</Value>
|
||||
</DataRecord>
|
||||
|
||||
</MBusData>
|
@ -23,7 +23,7 @@
|
||||
<Function>Instantaneous value</Function>
|
||||
<StorageNumber>0</StorageNumber>
|
||||
<Unit>Time Point (time & date)</Unit>
|
||||
<Value>2000-01-00T00:00:00</Value>
|
||||
<Value>1900-01-00T00:00:00</Value>
|
||||
</DataRecord>
|
||||
|
||||
<DataRecord id="2">
|
||||
|
Reference in New Issue
Block a user