Merge pull request #7 from lategoodbye/master
Migrate all new features also to mbus-protocol-aux.c
This commit is contained in:
commit
fd6e432213
@ -179,8 +179,8 @@ mbus_variable_vif vif_table[] = {
|
|||||||
{ 0x6B, 1.0e0, "bar", "Pressure" },
|
{ 0x6B, 1.0e0, "bar", "Pressure" },
|
||||||
|
|
||||||
/* E110 110n Time Point */
|
/* E110 110n Time Point */
|
||||||
{ 0x6C, 1.0e0, "-", "Time point" }, /* n = 0 date, data type G */
|
{ 0x6C, 1.0e0, "-", "Time point (date)" }, /* n = 0 date, data type G */
|
||||||
{ 0x6D, 1.0e0, "-", "Time point" }, /* n = 1 time & date, data type F */
|
{ 0x6D, 1.0e0, "-", "Time point (date & time)" }, /* n = 1 time & date, data type F */
|
||||||
|
|
||||||
/* E110 1110 Units for H.C.A. dimensionless */
|
/* E110 1110 Units for H.C.A. dimensionless */
|
||||||
{ 0x6E, 1.0e0, "Units for H.C.A.", "H.C.A." },
|
{ 0x6E, 1.0e0, "Units for H.C.A.", "H.C.A." },
|
||||||
@ -749,15 +749,23 @@ int mbus_variable_value_decode(mbus_data_record *record, double *value_out_real,
|
|||||||
*value_out_real = 0.0;
|
*value_out_real = 0.0;
|
||||||
*value_out_str = NULL;
|
*value_out_str = NULL;
|
||||||
*value_out_str_size = 0;
|
*value_out_str_size = 0;
|
||||||
|
u_char vif, vife;
|
||||||
|
struct tm time;
|
||||||
|
|
||||||
if (record)
|
if (record)
|
||||||
{
|
{
|
||||||
MBUS_DEBUG("coding = 0x%02X \n", record->drh.dib.dif);
|
MBUS_DEBUG("coding = 0x%02X \n", record->drh.dib.dif);
|
||||||
|
|
||||||
|
// ignore extension bit
|
||||||
|
vif = (record->drh.vib.vif & 0x7F);
|
||||||
|
vife = (record->drh.vib.vife[0] & 0x7F);
|
||||||
|
|
||||||
switch (record->drh.dib.dif & 0x0F)
|
switch (record->drh.dib.dif & 0x0F)
|
||||||
{
|
{
|
||||||
case 0x00: /* no data */
|
case 0x00: /* no data */
|
||||||
result = -1;
|
*value_out_str = (char*) malloc(1);
|
||||||
|
*value_out_str_size = 0;
|
||||||
|
result = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x01: /* 1 byte integer (8 bit) */
|
case 0x01: /* 1 byte integer (8 bit) */
|
||||||
@ -766,7 +774,21 @@ int mbus_variable_value_decode(mbus_data_record *record, double *value_out_real,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x02: /* 2 byte integer (16 bit) */
|
case 0x02: /* 2 byte integer (16 bit) */
|
||||||
*value_out_real = mbus_data_int_decode(record->data, 2);
|
// E110 1100 Time Point (date)
|
||||||
|
if (vif == 0x6C)
|
||||||
|
{
|
||||||
|
mbus_data_tm_decode(&time, record->data, 2);
|
||||||
|
*value_out_str = (char*) malloc(11);
|
||||||
|
*value_out_str_size = snprintf(*value_out_str, 11, "%04d-%02d-%02d",
|
||||||
|
(time.tm_year + 2000),
|
||||||
|
(time.tm_mon + 1),
|
||||||
|
time.tm_mday);
|
||||||
|
}
|
||||||
|
else // normal integer
|
||||||
|
{
|
||||||
|
*value_out_real = mbus_data_int_decode(record->data, 2);
|
||||||
|
}
|
||||||
|
|
||||||
result = 0;
|
result = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -776,22 +798,42 @@ int mbus_variable_value_decode(mbus_data_record *record, double *value_out_real,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x04: /* 4 byte integer (32 bit) */
|
case 0x04: /* 4 byte integer (32 bit) */
|
||||||
*value_out_real = mbus_data_int_decode(record->data, 4);
|
// 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, 4);
|
||||||
|
*value_out_str = (char*) malloc(20);
|
||||||
|
*value_out_str_size = snprintf(*value_out_str, 20, "%04d-%02d-%02dT%02d:%02d:%02d",
|
||||||
|
(time.tm_year + 2000),
|
||||||
|
(time.tm_mon + 1),
|
||||||
|
time.tm_mday,
|
||||||
|
time.tm_hour,
|
||||||
|
time.tm_min,
|
||||||
|
time.tm_sec);
|
||||||
|
}
|
||||||
|
else // normal integer
|
||||||
|
{
|
||||||
|
*value_out_real = mbus_data_int_decode(record->data, 4);
|
||||||
|
}
|
||||||
result = 0;
|
result = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x05: /* 32b real */
|
case 0x05: /* 32b real */
|
||||||
result = -2;
|
*value_out_real = mbus_data_float_decode(record->data);
|
||||||
MBUS_ERROR("32b real not implemented yet\n");
|
result = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x06: /* 6 byte integer (48 bit) */
|
case 0x06: /* 6 byte integer (48 bit) */
|
||||||
*value_out_real = mbus_data_long_decode(record->data, 6);
|
*value_out_real = mbus_data_long_long_decode(record->data, 6);
|
||||||
result = 0;
|
result = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x07: /* 8 byte integer (64 bit) */
|
case 0x07: /* 8 byte integer (64 bit) */
|
||||||
*value_out_real = mbus_data_long_decode(record->data, 8);
|
*value_out_real = mbus_data_long_long_decode(record->data, 8);
|
||||||
result = 0;
|
result = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -830,13 +872,15 @@ int mbus_variable_value_decode(mbus_data_record *record, double *value_out_real,
|
|||||||
}
|
}
|
||||||
|
|
||||||
case 0x0E: /* 12 digit BCD (40 bit) */
|
case 0x0E: /* 12 digit BCD (40 bit) */
|
||||||
result = -2;
|
*value_out_real = mbus_data_bcd_decode(record->data, 6);
|
||||||
MBUS_ERROR("12 digit BCD (40 bit) not implemented yet\n");
|
result = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0F: /* Special functions */
|
case 0x0F: /* Special functions */
|
||||||
result = -2;
|
*value_out_str = (char*) malloc(3 * record->data_len + 1);
|
||||||
MBUS_ERROR("Special functions not implemented yet");
|
*value_out_str_size = 3 * record->data_len;
|
||||||
|
mbus_data_bin_decode((u_char*)(*value_out_str), record->data, record->data_len, (3 * record->data_len + 1));
|
||||||
|
result = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -847,6 +891,7 @@ int mbus_variable_value_decode(mbus_data_record *record, double *value_out_real,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
MBUS_ERROR("record is null");
|
||||||
result = -3;
|
result = -3;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -864,58 +909,22 @@ mbus_vif_unit_normalize(int vif, double value, char **unit_out, double *value_ou
|
|||||||
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
switch (newVif) /* ignore the extension bit in this selection */
|
for(i=0; vif_table[i].vif < 0xfff; ++i)
|
||||||
{
|
{
|
||||||
/* E110 110n Time Point
|
if (vif_table[i].vif == newVif)
|
||||||
n = 0 date
|
{
|
||||||
n = 1 time & date
|
*unit_out = strdup(vif_table[i].unit);
|
||||||
data type G
|
*value_out = value * vif_table[i].exponent;
|
||||||
data type F */
|
*quantity_out = strdup(vif_table[i].quantity);
|
||||||
case 0x6C:
|
|
||||||
case 0x6C+1:
|
|
||||||
if (vif & 0x1)
|
|
||||||
{
|
|
||||||
*unit_out = strdup("Time Point (time & date)");
|
|
||||||
*quantity_out = strdup("Time Point (time & date)");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*unit_out = strdup("Time Point (date)");
|
|
||||||
*quantity_out = strdup("Time Point (date)");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* Manufacturer specific: 7Fh / FF */
|
|
||||||
case 0x7F:
|
|
||||||
case 0xFF:
|
|
||||||
*unit_out = strdup("Manufacturer specific");
|
|
||||||
*quantity_out = strdup("Manufacturer specific");
|
|
||||||
exponent = 0.0;
|
|
||||||
*value_out = 0.0;
|
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
}
|
||||||
|
|
||||||
default:
|
|
||||||
for(i=0; vif_table[i].vif < 0xfff; ++i)
|
|
||||||
{
|
|
||||||
if (vif_table[i].vif == newVif)
|
|
||||||
{
|
|
||||||
*unit_out = strdup(vif_table[i].unit);
|
|
||||||
*value_out = value * vif_table[i].exponent;
|
|
||||||
*quantity_out = strdup(vif_table[i].quantity);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*unit_out = strdup("Unknown (VIF=0x%.2X)");
|
|
||||||
*quantity_out = strdup("Unknown");
|
|
||||||
exponent = 0.0;
|
|
||||||
*value_out = 0.0;
|
|
||||||
return -1;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return -2;
|
*unit_out = strdup("Unknown (VIF=0x%.2X)");
|
||||||
|
*quantity_out = strdup("Unknown");
|
||||||
|
exponent = 0.0;
|
||||||
|
*value_out = 0.0;
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -952,7 +961,16 @@ mbus_vib_unit_normalize(mbus_value_information_block *vib, double value, char **
|
|||||||
MBUS_ERROR("%s: Error mbus_vif_unit_normalize\n", __PRETTY_FUNCTION__);
|
MBUS_ERROR("%s: Error mbus_vif_unit_normalize\n", __PRETTY_FUNCTION__);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else if (vib->vif == 0x7C)
|
||||||
|
{
|
||||||
|
// custom VIF
|
||||||
|
*unit_out = strdup("-");
|
||||||
|
*quantity_out = strdup(vib->custom_vif);
|
||||||
|
*value_out = 0.0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
int code = (vib->vif) & 0x7f;
|
int code = (vib->vif) & 0x7f;
|
||||||
if (0 != mbus_vif_unit_normalize(code, value, unit_out, value_out, quantity_out))
|
if (0 != mbus_vif_unit_normalize(code, value, unit_out, value_out, quantity_out))
|
||||||
{
|
{
|
||||||
@ -1057,6 +1075,10 @@ mbus_record *
|
|||||||
mbus_parse_variable_record(mbus_data_record *data)
|
mbus_parse_variable_record(mbus_data_record *data)
|
||||||
{
|
{
|
||||||
mbus_record * record = NULL;
|
mbus_record * record = NULL;
|
||||||
|
double value_out_real = 0.0; /**< raw value */
|
||||||
|
char * value_out_str = NULL;
|
||||||
|
int value_out_str_size = 0;
|
||||||
|
double real_val = 0.0; /**< normalized value */
|
||||||
|
|
||||||
if (!(record = mbus_record_new()))
|
if (!(record = mbus_record_new()))
|
||||||
{
|
{
|
||||||
@ -1066,20 +1088,42 @@ mbus_parse_variable_record(mbus_data_record *data)
|
|||||||
|
|
||||||
if (data->drh.dib.dif == 0x0F || data->drh.dib.dif == 0x1F) /* MBUS_DIB_DIF_VENDOR_SPECIFIC */
|
if (data->drh.dib.dif == 0x0F || data->drh.dib.dif == 0x1F) /* MBUS_DIB_DIF_VENDOR_SPECIFIC */
|
||||||
{
|
{
|
||||||
record->function_medium = strdup("Manufacturer specific");
|
if (data->drh.dib.dif == 0x1F)
|
||||||
|
{
|
||||||
|
record->function_medium = strdup("More records follow");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
record->function_medium = strdup("Manufacturer specific");
|
||||||
|
}
|
||||||
|
|
||||||
/* parsing of data not implemented yet
|
/* parsing of data not implemented yet
|
||||||
manufacturer specific data structures to end of user data */
|
manufacturer specific data structures to end of user data */
|
||||||
|
|
||||||
|
if (mbus_variable_value_decode(data, &value_out_real, &value_out_str, &value_out_str_size) != 0)
|
||||||
|
{
|
||||||
|
MBUS_ERROR("%s: problem with mbus_variable_value_decode\n", __PRETTY_FUNCTION__);
|
||||||
|
mbus_record_free(record);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value_out_str != NULL)
|
||||||
|
{
|
||||||
|
record->is_numeric = 0;
|
||||||
|
(record->value).str_val.value = value_out_str;
|
||||||
|
(record->value).str_val.size = value_out_str_size;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
record->is_numeric = 1;
|
||||||
|
(record->value).real_val = real_val;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
record->function_medium = strdup(mbus_data_record_function(data));
|
record->function_medium = strdup(mbus_data_record_function(data));
|
||||||
MBUS_DEBUG("record->function_medium = %s \n", record->function_medium);
|
MBUS_DEBUG("record->function_medium = %s \n", record->function_medium);
|
||||||
|
|
||||||
double value_out_real = 0.0; /**< raw value */
|
|
||||||
char * value_out_str = NULL;
|
|
||||||
int value_out_str_size = 0;
|
|
||||||
double real_val = 0.0; /**< normalized value */
|
|
||||||
|
|
||||||
if (mbus_variable_value_decode(data, &value_out_real, &value_out_str, &value_out_str_size) != 0)
|
if (mbus_variable_value_decode(data, &value_out_real, &value_out_str, &value_out_str_size) != 0)
|
||||||
{
|
{
|
||||||
MBUS_ERROR("%s: problem with mbus_variable_value_decode\n", __PRETTY_FUNCTION__);
|
MBUS_ERROR("%s: problem with mbus_variable_value_decode\n", __PRETTY_FUNCTION__);
|
||||||
@ -1110,9 +1154,96 @@ mbus_parse_variable_record(mbus_data_record *data)
|
|||||||
(record->value).real_val = real_val;
|
(record->value).real_val = real_val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return record;
|
return record;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
/// Generate XML for variable-length data
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
char *
|
||||||
|
mbus_data_variable_xml_normalized(mbus_data_variable *data)
|
||||||
|
{
|
||||||
|
mbus_data_record *record;
|
||||||
|
mbus_record *norm_record;
|
||||||
|
static char buff[8192];
|
||||||
|
char str_encoded[768];
|
||||||
|
size_t len = 0;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if (data)
|
||||||
|
{
|
||||||
|
len += snprintf(&buff[len], sizeof(buff) - len, "<MBusData>\n\n");
|
||||||
|
|
||||||
|
len += snprintf(&buff[len], sizeof(buff) - len, "%s", mbus_data_variable_header_xml(&(data->header)));
|
||||||
|
|
||||||
|
for (record = data->record, i = 0; record; record = record->next, i++)
|
||||||
|
{
|
||||||
|
norm_record = mbus_parse_variable_record(record);
|
||||||
|
|
||||||
|
len += snprintf(&buff[len], sizeof(buff) - len, " <DataRecord id=\"%zd\">\n", i);
|
||||||
|
|
||||||
|
if (norm_record != NULL)
|
||||||
|
{
|
||||||
|
mbus_str_xml_encode(str_encoded, norm_record->function_medium, sizeof(str_encoded));
|
||||||
|
len += snprintf(&buff[len], sizeof(buff) - len, " <Function>%s</Function>\n", str_encoded);
|
||||||
|
|
||||||
|
mbus_str_xml_encode(str_encoded, norm_record->unit, sizeof(str_encoded));
|
||||||
|
|
||||||
|
len += snprintf(&buff[len], sizeof(buff) - len, " <Unit>%s</Unit>\n", str_encoded);
|
||||||
|
|
||||||
|
mbus_str_xml_encode(str_encoded, norm_record->quantity, sizeof(str_encoded));
|
||||||
|
len += snprintf(&buff[len], sizeof(buff) - len, " <Quantity>%s</Quantity>\n", str_encoded);
|
||||||
|
|
||||||
|
|
||||||
|
if (norm_record->is_numeric)
|
||||||
|
{
|
||||||
|
len += snprintf(&buff[len], sizeof(buff) - len, " <Value>%f</Value>\n", norm_record->value.real_val);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mbus_str_xml_encode(str_encoded, norm_record->value.str_val.value, sizeof(str_encoded));
|
||||||
|
len += snprintf(&buff[len], sizeof(buff) - len, " <Value>%s</Value>\n", str_encoded);
|
||||||
|
}
|
||||||
|
|
||||||
|
mbus_record_free(norm_record);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
len += snprintf(&buff[len], sizeof(buff) - len, " </DataRecord>\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
len += snprintf(&buff[len], sizeof(buff) - len, "</MBusData>\n");
|
||||||
|
|
||||||
|
return buff;
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
/// Return a string containing an XML representation of the M-BUS frame data.
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
char *
|
||||||
|
mbus_frame_data_xml_normalized(mbus_frame_data *data)
|
||||||
|
{
|
||||||
|
if (data)
|
||||||
|
{
|
||||||
|
if (data->type == MBUS_DATA_TYPE_FIXED)
|
||||||
|
{
|
||||||
|
return mbus_data_fixed_xml(&(data->data_fix));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data->type == MBUS_DATA_TYPE_VARIABLE)
|
||||||
|
{
|
||||||
|
return mbus_data_variable_xml_normalized(&(data->data_var));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
mbus_handle *
|
mbus_handle *
|
||||||
mbus_connect_serial(const char * device)
|
mbus_connect_serial(const char * device)
|
||||||
|
@ -346,6 +346,24 @@ int mbus_vif_unit_normalize(int vif, double value, char **unit_out, double *valu
|
|||||||
*/
|
*/
|
||||||
int mbus_vib_unit_normalize(mbus_value_information_block *vib, double value, char **unit_out, double *value_out, char ** quantity_out);
|
int mbus_vib_unit_normalize(mbus_value_information_block *vib, double value, char **unit_out, double *value_out, char ** quantity_out);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate XML for normalized variable-length data
|
||||||
|
*
|
||||||
|
* @param data variable-length data
|
||||||
|
*
|
||||||
|
* @return string with XML
|
||||||
|
*/
|
||||||
|
char * mbus_data_variable_xml_normalized(mbus_data_variable *data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a string containing an XML representation of the normalized M-BUS frame data.
|
||||||
|
*
|
||||||
|
* @param data M-Bus frame data
|
||||||
|
*
|
||||||
|
* @return string with XML
|
||||||
|
*/
|
||||||
|
char * mbus_frame_data_xml_normalized(mbus_frame_data *data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Iterate over secondary addresses, send a probe package to all addresses matching
|
* Iterate over secondary addresses, send a probe package to all addresses matching
|
||||||
* the given addresses mask.
|
* the given addresses mask.
|
||||||
|
@ -2943,32 +2943,36 @@ mbus_str_xml_encode(u_char *dst, const u_char *src, size_t max_len)
|
|||||||
i = 0;
|
i = 0;
|
||||||
len = 0;
|
len = 0;
|
||||||
|
|
||||||
while((len+6) < max_len) {
|
if (src != NULL)
|
||||||
if (src[i] == '\0')
|
{
|
||||||
|
while((len+6) < max_len)
|
||||||
{
|
{
|
||||||
break;
|
if (src[i] == '\0')
|
||||||
}
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
switch (src[i])
|
switch (src[i])
|
||||||
{
|
{
|
||||||
case '&':
|
case '&':
|
||||||
len += snprintf(&dst[len], max_len - len, "&");
|
len += snprintf(&dst[len], max_len - len, "&");
|
||||||
break;
|
break;
|
||||||
case '<':
|
case '<':
|
||||||
len += snprintf(&dst[len], max_len - len, "<");
|
len += snprintf(&dst[len], max_len - len, "<");
|
||||||
break;
|
break;
|
||||||
case '>':
|
case '>':
|
||||||
len += snprintf(&dst[len], max_len - len, ">");
|
len += snprintf(&dst[len], max_len - len, ">");
|
||||||
break;
|
break;
|
||||||
case '"':
|
case '"':
|
||||||
len += snprintf(&dst[len], max_len - len, """);
|
len += snprintf(&dst[len], max_len - len, """);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
dst[len++] = src[i];
|
dst[len++] = src[i];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dst[len] = '\0';
|
dst[len] = '\0';
|
||||||
|
Loading…
x
Reference in New Issue
Block a user