diff --git a/bin/mbus-serial-request-data.c b/bin/mbus-serial-request-data.c
index 1152a04..20e3fa6 100755
--- a/bin/mbus-serial-request-data.c
+++ b/bin/mbus-serial-request-data.c
@@ -15,6 +15,35 @@
static int debug = 0;
+//
+// init slave to get really the beginning of the records
+//
+static int
+init_slaves(mbus_handle *handle)
+{
+ if (debug)
+ printf("%s: debug: sending init frame #1\n", __PRETTY_FUNCTION__);
+
+ if (mbus_send_ping_frame(handle, MBUS_ADDRESS_NETWORK_LAYER, 1) == -1)
+ {
+ return 0;
+ }
+
+ //
+ // resend SND_NKE, maybe the first get lost
+ //
+
+ if (debug)
+ printf("%s: debug: sending init frame #2\n", __PRETTY_FUNCTION__);
+
+ if (mbus_send_ping_frame(handle, MBUS_ADDRESS_NETWORK_LAYER, 1) == -1)
+ {
+ return 0;
+ }
+
+ return 1;
+}
+
//------------------------------------------------------------------------------
// Scan for devices using secondary addressing.
//------------------------------------------------------------------------------
@@ -79,15 +108,24 @@ main(int argc, char **argv)
if (mbus_connect(handle) == -1)
{
fprintf(stderr,"Failed to setup connection to M-bus gateway\n");
+ mbus_context_free(handle);
return 1;
}
if (mbus_serial_set_baudrate(handle, baudrate) == -1)
{
fprintf(stderr,"Failed to set baud rate.\n");
+ mbus_disconnect(handle);
+ mbus_context_free(handle);
return 1;
}
+ if (init_slaves(handle) == 0)
+ {
+ mbus_disconnect(handle);
+ mbus_context_free(handle);
+ return 1;
+ }
if (mbus_is_secondary_address(addr_str))
{
@@ -100,36 +138,40 @@ main(int argc, char **argv)
if (ret == MBUS_PROBE_COLLISION)
{
fprintf(stderr, "%s: Error: The address mask [%s] matches more than one device.\n", __PRETTY_FUNCTION__, addr_str);
+ mbus_disconnect(handle);
+ mbus_context_free(handle);
return 1;
}
else if (ret == MBUS_PROBE_NOTHING)
{
fprintf(stderr, "%s: Error: The selected secondary address does not match any device [%s].\n", __PRETTY_FUNCTION__, addr_str);
+ mbus_disconnect(handle);
+ mbus_context_free(handle);
return 1;
}
else if (ret == MBUS_PROBE_ERROR)
{
fprintf(stderr, "%s: Error: Failed to select secondary address [%s].\n", __PRETTY_FUNCTION__, addr_str);
+ mbus_disconnect(handle);
+ mbus_context_free(handle);
return 1;
}
// else MBUS_PROBE_SINGLE
-
- if (mbus_send_request_frame(handle, MBUS_ADDRESS_NETWORK_LAYER) == -1)
- {
- fprintf(stderr, "Failed to send M-Bus request frame.\n");
- return 1;
- }
+
+ address = MBUS_ADDRESS_NETWORK_LAYER;
}
else
{
// primary addressing
-
address = atoi(addr_str);
- if (mbus_send_request_frame(handle, address) == -1)
- {
- fprintf(stderr, "Failed to send M-Bus request frame.\n");
- return 1;
- }
+ }
+
+ if (mbus_send_request_frame(handle, address) == -1)
+ {
+ fprintf(stderr, "Failed to send M-Bus request frame.\n");
+ mbus_disconnect(handle);
+ mbus_context_free(handle);
+ return 1;
}
if (mbus_recv_frame(handle, &reply) != MBUS_RECV_RESULT_OK)
@@ -139,22 +181,32 @@ main(int argc, char **argv)
}
//
- // parse data and print in XML format
+ // dump hex data if debug is true
//
if (debug)
{
mbus_frame_print(&reply);
}
+ //
+ // parse data
+ //
if (mbus_frame_data_parse(&reply, &reply_data) == -1)
{
fprintf(stderr, "M-bus data parse error: %s\n", mbus_error_str());
+ mbus_disconnect(handle);
+ mbus_context_free(handle);
return 1;
}
+ //
+ // generate XML and print to standard output
+ //
if ((xml_result = mbus_frame_data_xml(&reply_data)) == NULL)
{
fprintf(stderr, "Failed to generate XML representation of MBUS frame: %s\n", mbus_error_str());
+ mbus_disconnect(handle);
+ mbus_context_free(handle);
return 1;
}
diff --git a/bin/mbus-serial-scan.c b/bin/mbus-serial-scan.c
index 8a935c9..e7babd7 100755
--- a/bin/mbus-serial-scan.c
+++ b/bin/mbus-serial-scan.c
@@ -21,7 +21,7 @@ int ping_address(mbus_handle *handle, mbus_frame *reply, int address)
memset((void *)reply, 0, sizeof(mbus_frame));
- for (i = 0; i <= handle->max_retry; i++)
+ for (i = 0; i <= handle->max_search_retry; i++)
{
if (debug)
{
@@ -126,7 +126,7 @@ main(int argc, char **argv)
return 1;
}
- if (mbus_context_set_option(handle, MBUS_OPTION_MAX_RETRY, retries) == -1)
+ if (mbus_context_set_option(handle, MBUS_OPTION_MAX_SEARCH_RETRY, retries) == -1)
{
fprintf(stderr,"Failed to set retry count\n");
return 1;
diff --git a/bin/mbus-tcp-scan.c b/bin/mbus-tcp-scan.c
index 70ed102..3d96194 100755
--- a/bin/mbus-tcp-scan.c
+++ b/bin/mbus-tcp-scan.c
@@ -21,7 +21,7 @@ int ping_address(mbus_handle *handle, mbus_frame *reply, int address)
memset((void *)reply, 0, sizeof(mbus_frame));
- for (i = 0; i <= handle->max_retry; i++)
+ for (i = 0; i <= handle->max_search_retry; i++)
{
if (debug)
{
@@ -112,7 +112,7 @@ main(int argc, char **argv)
return 1;
}
- if (mbus_context_set_option(handle, MBUS_OPTION_MAX_RETRY, retries) == -1)
+ if (mbus_context_set_option(handle, MBUS_OPTION_MAX_SEARCH_RETRY, retries) == -1)
{
fprintf(stderr,"Failed to set retry count\n");
return 1;
diff --git a/mbus/mbus-protocol-aux.c b/mbus/mbus-protocol-aux.c
index be7312d..d78e187 100755
--- a/mbus/mbus-protocol-aux.c
+++ b/mbus/mbus-protocol-aux.c
@@ -214,9 +214,17 @@ mbus_variable_vif vif_table[] = {
/* E111 1010 Bus Address */
{ 0x7A, 1.0, "", "Bus Address" },
-
- /* Manufacturer specific: 7Fh / FF */
+
+ /* Any VIF: 7Eh */
+ { 0x7E, 1.0, "", "Any VIF" },
+
+ /* Manufacturer specific: 7Fh */
{ 0x7F, 1.0, "", "Manufacturer specific" },
+
+ /* Any VIF: 7Eh */
+ { 0xFE, 1.0, "", "Any VIF" },
+
+ /* Manufacturer specific: FFh */
{ 0xFF, 1.0, "", "Manufacturer specific" },
@@ -567,32 +575,22 @@ mbus_variable_vif vif_table[] = {
{ 0x235, 1.0e0, "Reserved", "Reserved" },
{ 0x236, 1.0e0, "Reserved", "Reserved" },
{ 0x237, 1.0e0, "Reserved", "Reserved" },
-
- /* E101 10nn Flow Temperature 10(nn-3) °F 0.001°F to 1°F */
- { 0x238, 1.0e-3, "°F", "Flow temperature" },
- { 0x239, 1.0e-2, "°F", "Flow temperature" },
- { 0x23A, 1.0e-1, "°F", "Flow temperature" },
- { 0x23B, 1.0e0, "°F", "Flow temperature" },
-
- /* E101 11nn Return Temperature 10(nn-3) °F 0.001°F to 1°F */
- { 0x23C, 1.0e-3, "°F", "Return temperature" },
- { 0x23D, 1.0e-2, "°F", "Return temperature" },
- { 0x23E, 1.0e-1, "°F", "Return temperature" },
- { 0x23F, 1.0e0, "°F", "Return temperature" },
-
- /* E110 00nn Temperature Difference 10(nn-3) °F 0.001°F to 1°F */
- { 0x240, 1.0e-3, "°F", "Temperature difference" },
- { 0x241, 1.0e-2, "°F", "Temperature difference" },
- { 0x242, 1.0e-1, "°F", "Temperature difference" },
- { 0x243, 1.0e0, "°F", "Temperature difference" },
-
- /* E110 01nn External Temperature 10(nn-3) °F 0.001°F to 1°F */
- { 0x244, 1.0e-3, "°F", "External temperature" },
- { 0x245, 1.0e-2, "°F", "External temperature" },
- { 0x246, 1.0e-1, "°F", "External temperature" },
- { 0x247, 1.0e0, "°F", "External temperature" },
-
- /* E110 1nnn Reserved */
+ { 0x238, 1.0e0, "Reserved", "Reserved" },
+ { 0x239, 1.0e0, "Reserved", "Reserved" },
+ { 0x23A, 1.0e0, "Reserved", "Reserved" },
+ { 0x23B, 1.0e0, "Reserved", "Reserved" },
+ { 0x23C, 1.0e0, "Reserved", "Reserved" },
+ { 0x23D, 1.0e0, "Reserved", "Reserved" },
+ { 0x23E, 1.0e0, "Reserved", "Reserved" },
+ { 0x23F, 1.0e0, "Reserved", "Reserved" },
+ { 0x240, 1.0e0, "Reserved", "Reserved" },
+ { 0x241, 1.0e0, "Reserved", "Reserved" },
+ { 0x242, 1.0e0, "Reserved", "Reserved" },
+ { 0x243, 1.0e0, "Reserved", "Reserved" },
+ { 0x244, 1.0e0, "Reserved", "Reserved" },
+ { 0x245, 1.0e0, "Reserved", "Reserved" },
+ { 0x246, 1.0e0, "Reserved", "Reserved" },
+ { 0x247, 1.0e0, "Reserved", "Reserved" },
{ 0x248, 1.0e0, "Reserved", "Reserved" },
{ 0x249, 1.0e0, "Reserved", "Reserved" },
{ 0x24A, 1.0e0, "Reserved", "Reserved" },
@@ -601,28 +599,70 @@ mbus_variable_vif vif_table[] = {
{ 0x24D, 1.0e0, "Reserved", "Reserved" },
{ 0x24E, 1.0e0, "Reserved", "Reserved" },
{ 0x24F, 1.0e0, "Reserved", "Reserved" },
+ { 0x250, 1.0e0, "Reserved", "Reserved" },
+ { 0x251, 1.0e0, "Reserved", "Reserved" },
+ { 0x252, 1.0e0, "Reserved", "Reserved" },
+ { 0x253, 1.0e0, "Reserved", "Reserved" },
+ { 0x254, 1.0e0, "Reserved", "Reserved" },
+ { 0x255, 1.0e0, "Reserved", "Reserved" },
+ { 0x256, 1.0e0, "Reserved", "Reserved" },
+ { 0x257, 1.0e0, "Reserved", "Reserved" },
+
+ /* E101 10nn Flow Temperature 10(nn-3) °F 0.001°F to 1°F */
+ { 0x258, 1.0e-3, "°F", "Flow temperature" },
+ { 0x259, 1.0e-2, "°F", "Flow temperature" },
+ { 0x25A, 1.0e-1, "°F", "Flow temperature" },
+ { 0x25B, 1.0e0, "°F", "Flow temperature" },
+
+ /* E101 11nn Return Temperature 10(nn-3) °F 0.001°F to 1°F */
+ { 0x25C, 1.0e-3, "°F", "Return temperature" },
+ { 0x25D, 1.0e-2, "°F", "Return temperature" },
+ { 0x25E, 1.0e-1, "°F", "Return temperature" },
+ { 0x25F, 1.0e0, "°F", "Return temperature" },
+
+ /* E110 00nn Temperature Difference 10(nn-3) °F 0.001°F to 1°F */
+ { 0x260, 1.0e-3, "°F", "Temperature difference" },
+ { 0x261, 1.0e-2, "°F", "Temperature difference" },
+ { 0x262, 1.0e-1, "°F", "Temperature difference" },
+ { 0x263, 1.0e0, "°F", "Temperature difference" },
+
+ /* E110 01nn External Temperature 10(nn-3) °F 0.001°F to 1°F */
+ { 0x264, 1.0e-3, "°F", "External temperature" },
+ { 0x265, 1.0e-2, "°F", "External temperature" },
+ { 0x266, 1.0e-1, "°F", "External temperature" },
+ { 0x267, 1.0e0, "°F", "External temperature" },
+
+ /* E110 1nnn Reserved */
+ { 0x268, 1.0e0, "Reserved", "Reserved" },
+ { 0x269, 1.0e0, "Reserved", "Reserved" },
+ { 0x26A, 1.0e0, "Reserved", "Reserved" },
+ { 0x26B, 1.0e0, "Reserved", "Reserved" },
+ { 0x26C, 1.0e0, "Reserved", "Reserved" },
+ { 0x26D, 1.0e0, "Reserved", "Reserved" },
+ { 0x26E, 1.0e0, "Reserved", "Reserved" },
+ { 0x26F, 1.0e0, "Reserved", "Reserved" },
/* E111 00nn Cold / Warm Temperature Limit 10(nn-3) °F 0.001°F to 1°F */
- { 0x250, 1.0e-3, "°F", "Cold / Warm Temperature Limit" },
- { 0x251, 1.0e-2, "°F", "Cold / Warm Temperature Limit" },
- { 0x252, 1.0e-1, "°F", "Cold / Warm Temperature Limit" },
- { 0x253, 1.0e0, "°F", "Cold / Warm Temperature Limit" },
+ { 0x270, 1.0e-3, "°F", "Cold / Warm Temperature Limit" },
+ { 0x271, 1.0e-2, "°F", "Cold / Warm Temperature Limit" },
+ { 0x272, 1.0e-1, "°F", "Cold / Warm Temperature Limit" },
+ { 0x273, 1.0e0, "°F", "Cold / Warm Temperature Limit" },
/* E111 01nn Cold / Warm Temperature Limit 10(nn-3) °C 0.001°C to 1°C */
- { 0x254, 1.0e-3, "°C", "Cold / Warm Temperature Limit" },
- { 0x255, 1.0e-2, "°C", "Cold / Warm Temperature Limit" },
- { 0x256, 1.0e-1, "°C", "Cold / Warm Temperature Limit" },
- { 0x257, 1.0e0, "°C", "Cold / Warm Temperature Limit" },
+ { 0x274, 1.0e-3, "°C", "Cold / Warm Temperature Limit" },
+ { 0x275, 1.0e-2, "°C", "Cold / Warm Temperature Limit" },
+ { 0x276, 1.0e-1, "°C", "Cold / Warm Temperature Limit" },
+ { 0x277, 1.0e0, "°C", "Cold / Warm Temperature Limit" },
/* E111 1nnn cumul. count max power § 10(nnn-3) W 0.001W to 10000W */
- { 0x258, 1.0e-3, "W", "Cumul count max power" },
- { 0x259, 1.0e-3, "W", "Cumul count max power" },
- { 0x25A, 1.0e-1, "W", "Cumul count max power" },
- { 0x25B, 1.0e0, "W", "Cumul count max power" },
- { 0x25C, 1.0e1, "W", "Cumul count max power" },
- { 0x25D, 1.0e2, "W", "Cumul count max power" },
- { 0x25E, 1.0e3, "W", "Cumul count max power" },
- { 0x25F, 1.0e4, "W", "Cumul count max power" },
+ { 0x278, 1.0e-3, "W", "Cumul count max power" },
+ { 0x279, 1.0e-3, "W", "Cumul count max power" },
+ { 0x27A, 1.0e-1, "W", "Cumul count max power" },
+ { 0x27B, 1.0e0, "W", "Cumul count max power" },
+ { 0x27C, 1.0e1, "W", "Cumul count max power" },
+ { 0x27D, 1.0e2, "W", "Cumul count max power" },
+ { 0x27E, 1.0e3, "W", "Cumul count max power" },
+ { 0x27F, 1.0e4, "W", "Cumul count max power" },
/* End of array */
{ 0xFFFF, 0.0, "", "" },
@@ -794,6 +834,9 @@ int mbus_variable_value_decode(mbus_data_record *record, double *value_out_real,
int result = 0;
unsigned char vif, vife;
struct tm time;
+ int value_out_int;
+ long value_out_long;
+ long long value_out_long_long;
*value_out_real = 0.0;
*value_out_str = NULL;
*value_out_str_size = 0;
@@ -806,7 +849,7 @@ int mbus_variable_value_decode(mbus_data_record *record, double *value_out_real,
vif = (record->drh.vib.vif & MBUS_DIB_VIF_WITHOUT_EXTENSION);
vife = (record->drh.vib.vife[0] & MBUS_DIB_VIF_WITHOUT_EXTENSION);
- switch (record->drh.dib.dif & 0x0F)
+ switch (record->drh.dib.dif & MBUS_DATA_RECORD_DIF_MASK_DATA)
{
case 0x00: /* no data */
if ((*value_out_str = (char*) malloc(1)) == NULL)
@@ -819,8 +862,8 @@ int mbus_variable_value_decode(mbus_data_record *record, double *value_out_real,
break;
case 0x01: /* 1 byte integer (8 bit) */
- *value_out_real = mbus_data_int_decode(record->data, 1);
- result = 0;
+ result = mbus_data_int_decode(record->data, 1, &value_out_int);
+ *value_out_real = value_out_int;
break;
case 0x02: /* 2 byte integer (16 bit) */
@@ -837,18 +880,18 @@ int mbus_variable_value_decode(mbus_data_record *record, double *value_out_real,
(time.tm_year + 2000),
(time.tm_mon + 1),
time.tm_mday);
+ result = 0;
}
else // normal integer
{
- *value_out_real = mbus_data_int_decode(record->data, 2);
+ result = mbus_data_int_decode(record->data, 2, &value_out_int);
+ *value_out_real = value_out_int;
}
-
- result = 0;
break;
case 0x03: /* 3 byte integer (24 bit) */
- *value_out_real = mbus_data_int_decode(record->data, 3);
- result = 0;
+ result = mbus_data_int_decode(record->data, 3, &value_out_int);
+ *value_out_real = value_out_int;
break;
case 0x04: /* 4 byte integer (32 bit) */
@@ -872,12 +915,13 @@ int mbus_variable_value_decode(mbus_data_record *record, double *value_out_real,
time.tm_hour,
time.tm_min,
time.tm_sec);
+ result = 0;
}
else // normal integer
{
- *value_out_real = mbus_data_int_decode(record->data, 4);
+ result = mbus_data_int_decode(record->data, 4, &value_out_int);
+ *value_out_real = value_out_int;
}
- result = 0;
break;
case 0x05: /* 32b real */
@@ -886,13 +930,13 @@ int mbus_variable_value_decode(mbus_data_record *record, double *value_out_real,
break;
case 0x06: /* 6 byte integer (48 bit) */
- *value_out_real = mbus_data_long_long_decode(record->data, 6);
- result = 0;
+ 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) */
- *value_out_real = mbus_data_long_long_decode(record->data, 8);
- result = 0;
+ result = mbus_data_long_long_decode(record->data, 8, &value_out_long_long);
+ *value_out_real = value_out_long_long;
break;
case 0x09: /* 2 digit BCD (8 bit) */
@@ -1112,6 +1156,9 @@ mbus_record_new()
record->unit = NULL;
record->function_medium = NULL;
record->quantity = NULL;
+ record->device = -1;
+ record->tariff = -1;
+ record->storage_number = 0;
return record;
}
@@ -1177,7 +1224,7 @@ mbus_parse_fixed_record(char status_byte, char medium_unit, unsigned char *data)
}
else
{
- value = mbus_data_int_decode(data, 4);
+ mbus_data_long_decode(data, 4, &value);
}
record->unit = NULL;
@@ -1213,6 +1260,10 @@ mbus_parse_variable_record(mbus_data_record *data)
MBUS_ERROR("%s: memory allocation error\n", __PRETTY_FUNCTION__);
return NULL;
}
+
+ record->storage_number = mbus_data_record_storage_number(data);
+ record->tariff = mbus_data_record_tariff(data);
+ record->device = mbus_data_record_device(data);
if ((data->drh.dib.dif == MBUS_DIB_DIF_MANUFACTURER_SPECIFIC) ||
(data->drh.dib.dif == MBUS_DIB_DIF_MORE_RECORDS_FOLLOW)) /* MBUS_DIB_DIF_VENDOR_SPECIFIC */
@@ -1351,6 +1402,14 @@ mbus_data_variable_xml_normalized(mbus_data_variable *data)
{
mbus_str_xml_encode(str_encoded, norm_record->function_medium, sizeof(str_encoded));
len += snprintf(&buff[len], buff_size - len, " %s\n", str_encoded);
+
+ len += snprintf(&buff[len], buff_size - len, " %ld\n", norm_record->storage_number);
+
+ if (norm_record->tariff >= 0)
+ {
+ len += snprintf(&buff[len], buff_size - len, " %ld\n", norm_record->tariff);
+ len += snprintf(&buff[len], buff_size - len, " %d\n", norm_record->device);
+ }
mbus_str_xml_encode(str_encoded, norm_record->unit, sizeof(str_encoded));
@@ -1430,7 +1489,8 @@ mbus_context_serial(const char *device)
return NULL;
}
- handle->max_retry = 3;
+ handle->max_data_retry = 3;
+ handle->max_search_retry = 1;
handle->is_serial = 1;
handle->purge_first_frame = MBUS_FRAME_PURGE_M2S;
handle->auxdata = serial_data;
@@ -1477,7 +1537,8 @@ mbus_context_tcp(const char *host, uint16_t port)
return NULL;
}
- handle->max_retry = 3;
+ handle->max_data_retry = 3;
+ handle->max_search_retry = 1;
handle->is_serial = 0;
handle->purge_first_frame = MBUS_FRAME_PURGE_M2S;
handle->auxdata = tcp_data;
@@ -1549,10 +1610,17 @@ mbus_context_set_option(mbus_handle * handle, mbus_context_option option, long v
switch (option)
{
- case MBUS_OPTION_MAX_RETRY:
+ case MBUS_OPTION_MAX_DATA_RETRY:
if ((value >= 0) && (value <= 9))
{
- handle->max_retry = value;
+ handle->max_data_retry = value;
+ return 0;
+ }
+ break;
+ case MBUS_OPTION_MAX_SEARCH_RETRY:
+ if ((value >= 0) && (value <= 9))
+ {
+ handle->max_search_retry = value;
return 0;
}
break;
@@ -1934,7 +2002,7 @@ mbus_sendrecv_request(mbus_handle *handle, int address, mbus_frame *reply, int m
while (more_frames)
{
- if (retry > handle->max_retry)
+ if (retry > handle->max_data_retry)
{
// Give up
retval = 1;
@@ -2155,7 +2223,7 @@ mbus_select_secondary_address(mbus_handle * handle, const char *mask)
int
mbus_probe_secondary_address(mbus_handle *handle, const char *mask, char *matching_addr)
{
- int ret;
+ int ret, i;
mbus_frame reply;
if (mask == NULL || matching_addr == NULL || strlen(mask) != 16)
@@ -2164,68 +2232,77 @@ mbus_probe_secondary_address(mbus_handle *handle, const char *mask, char *matchi
return MBUS_PROBE_ERROR;
}
- ret = mbus_select_secondary_address(handle, mask);
-
- if (ret == MBUS_PROBE_SINGLE)
+ for (i = 0; i <= handle->max_search_retry; i++)
{
- /* send a data request command to find out the full address */
- if (mbus_send_request_frame(handle, MBUS_ADDRESS_NETWORK_LAYER) == -1)
- {
- MBUS_ERROR("%s: Failed to send request to selected secondary device [mask %s]: %s.\n",
- __PRETTY_FUNCTION__,
- mask,
- mbus_error_str());
- return MBUS_PROBE_ERROR;
- }
+ ret = mbus_select_secondary_address(handle, mask);
- memset((void *)&reply, 0, sizeof(mbus_frame));
- ret = mbus_recv_frame(handle, &reply);
+ if (ret == MBUS_PROBE_SINGLE)
+ {
+ /* send a data request command to find out the full address */
+ if (mbus_send_request_frame(handle, MBUS_ADDRESS_NETWORK_LAYER) == -1)
+ {
+ MBUS_ERROR("%s: Failed to send request to selected secondary device [mask %s]: %s.\n",
+ __PRETTY_FUNCTION__,
+ mask,
+ mbus_error_str());
+ return MBUS_PROBE_ERROR;
+ }
- if (ret == MBUS_RECV_RESULT_TIMEOUT)
- {
- return MBUS_PROBE_NOTHING;
- }
+ memset((void *)&reply, 0, sizeof(mbus_frame));
+ ret = mbus_recv_frame(handle, &reply);
- if (ret == MBUS_RECV_RESULT_INVALID)
- {
- /* check for more data (collision) */
- mbus_purge_frames(handle);
- return MBUS_PROBE_COLLISION;
- }
-
- /* check for more data (collision) */
- if (mbus_purge_frames(handle))
- {
- return MBUS_PROBE_COLLISION;
- }
-
- if (mbus_frame_type(&reply) == MBUS_FRAME_TYPE_LONG)
- {
- char *addr = mbus_frame_get_secondary_address(&reply);
-
- if (addr == NULL)
+ if (ret == MBUS_RECV_RESULT_TIMEOUT)
{
- // show error message, but procede with scan
- MBUS_ERROR("Failed to generate secondary address from M-Bus reply frame: %s\n", mbus_error_str());
return MBUS_PROBE_NOTHING;
}
- snprintf(matching_addr, 17, "%s", addr);
-
- if (handle->found_event)
+ if (ret == MBUS_RECV_RESULT_INVALID)
{
- handle->found_event(handle,&reply);
- }
+ /* check for more data (collision) */
+ mbus_purge_frames(handle);
+ return MBUS_PROBE_COLLISION;
+ }
- return MBUS_PROBE_SINGLE;
- }
- else
- {
- MBUS_ERROR("%s: Unexpected reply for address [mask %s]. Expected long frame.\n",
- __PRETTY_FUNCTION__, mask);
- return MBUS_PROBE_NOTHING;
- }
- }
+ /* check for more data (collision) */
+ if (mbus_purge_frames(handle))
+ {
+ return MBUS_PROBE_COLLISION;
+ }
+
+ if (mbus_frame_type(&reply) == MBUS_FRAME_TYPE_LONG)
+ {
+ char *addr = mbus_frame_get_secondary_address(&reply);
+
+ if (addr == NULL)
+ {
+ // show error message, but procede with scan
+ MBUS_ERROR("Failed to generate secondary address from M-Bus reply frame: %s\n",
+ mbus_error_str());
+ return MBUS_PROBE_NOTHING;
+ }
+
+ snprintf(matching_addr, 17, "%s", addr);
+
+ if (handle->found_event)
+ {
+ handle->found_event(handle,&reply);
+ }
+
+ return MBUS_PROBE_SINGLE;
+ }
+ else
+ {
+ MBUS_ERROR("%s: Unexpected reply for address [mask %s]. Expected long frame.\n",
+ __PRETTY_FUNCTION__, mask);
+ return MBUS_PROBE_NOTHING;
+ }
+ }
+ else if ((ret == MBUS_PROBE_ERROR) ||
+ (ret == MBUS_PROBE_COLLISION))
+ {
+ break;
+ }
+ }
return ret;
}
@@ -2252,7 +2329,6 @@ int mbus_read_slave(mbus_handle * handle, mbus_address *address, mbus_frame * re
{
/* secondary addressing */
int probe_ret;
- char matching_addr[16];
if (address->secondary == NULL)
{
@@ -2261,7 +2337,7 @@ int mbus_read_slave(mbus_handle * handle, mbus_address *address, mbus_frame * re
return -1;
}
- probe_ret = mbus_probe_secondary_address(handle, address->secondary, matching_addr);
+ probe_ret = mbus_select_secondary_address(handle, address->secondary);
if (probe_ret == MBUS_PROBE_COLLISION)
{
@@ -2338,6 +2414,7 @@ mbus_scan_2nd_address_range(mbus_handle * handle, int pos, char *addr_mask)
if (mask[pos] == 'f' || mask[pos] == 'F')
{
+ // mask[pos] is a wildcard -> enumerate all 0..9 at this position
i_start = 0;
i_end = 9;
}
@@ -2345,44 +2422,50 @@ mbus_scan_2nd_address_range(mbus_handle * handle, int pos, char *addr_mask)
{
if (pos < 15)
{
+ // mask[pos] is not a wildcard -> don't iterate, recursively check pos+1
mbus_scan_2nd_address_range(handle, pos+1, mask);
}
else
{
+ // .. except if we're at the last pos (==15) and this isn't a wildcard we still need to send the probe
i_start = (int)(mask[pos] - '0');
i_end = (int)(mask[pos] - '0');
}
}
- for (i = 0; i <= 9; i++)
+ // skip the scanning if we're returning from the (pos < 15) case above
+ if (mask[pos] == 'f' || mask[pos] == 'F' || pos == 15)
{
- mask[pos] = '0'+i;
-
- if (handle->scan_progress)
- handle->scan_progress(handle,mask);
-
- probe_ret = mbus_probe_secondary_address(handle, mask, matching_mask);
-
- if (probe_ret == MBUS_PROBE_SINGLE)
+ for (i = i_start; i <= i_end; i++)
{
- if (!handle->found_event)
+ mask[pos] = '0'+i;
+
+ if (handle->scan_progress)
+ handle->scan_progress(handle,mask);
+
+ probe_ret = mbus_probe_secondary_address(handle, mask, matching_mask);
+
+ if (probe_ret == MBUS_PROBE_SINGLE)
{
- printf("Found a device on secondary address %s [using address mask %s]\n", matching_mask, mask);
+ if (!handle->found_event)
+ {
+ printf("Found a device on secondary address %s [using address mask %s]\n", matching_mask, mask);
+ }
+ }
+ else if (probe_ret == MBUS_PROBE_COLLISION)
+ {
+ // collision, more than one device matching, restrict the search mask further
+ mbus_scan_2nd_address_range(handle, pos+1, mask);
+ }
+ else if (probe_ret == MBUS_PROBE_NOTHING)
+ {
+ // nothing... move on to next address mask
+ }
+ else // MBUS_PROBE_ERROR
+ {
+ MBUS_ERROR("%s: Failed to probe secondary address [%s].\n", __PRETTY_FUNCTION__, mask);
+ return -1;
}
- }
- else if (probe_ret == MBUS_PROBE_COLLISION)
- {
- // collision, more than one device matching, restrict the search mask further
- mbus_scan_2nd_address_range(handle, pos+1, mask);
- }
- else if (probe_ret == MBUS_PROBE_NOTHING)
- {
- // nothing... move on to next address mask
- }
- else // MBUS_PROBE_ERROR
- {
- MBUS_ERROR("%s: Failed to probe secondary address [%s].\n", __PRETTY_FUNCTION__, mask);
- return -1;
}
}
diff --git a/mbus/mbus-protocol-aux.h b/mbus/mbus-protocol-aux.h
index 2cb61ec..52cfc54 100755
--- a/mbus/mbus-protocol-aux.h
+++ b/mbus/mbus-protocol-aux.h
@@ -85,7 +85,8 @@ extern "C" {
*/
typedef struct _mbus_handle {
int fd;
- int max_retry;
+ int max_data_retry;
+ int max_search_retry;
char purge_first_frame;
char is_serial; /**< _handle type (non zero for serial) */
int (*open) (struct _mbus_handle *handle);
@@ -142,13 +143,17 @@ typedef struct _mbus_record {
char *unit; /**< Quantity unit (e.g. Wh) */
char *function_medium; /**< Quantity medium or function (e.g. Electricity) */
char *quantity; /**< Quantity type (e.g. Energy) */
+ int device; /**< Quantity device */
+ long tariff; /**< Quantity tariff */
+ long storage_number; /**< Quantity storage number */
} mbus_record;
/**
* MBus handle option enumeration
*/
typedef enum _mbus_context_option {
- MBUS_OPTION_MAX_RETRY, /**< option defines the maximum attempts of data retransmission */
+ MBUS_OPTION_MAX_DATA_RETRY, /**< option defines the maximum attempts of data request retransmission */
+ MBUS_OPTION_MAX_SEARCH_RETRY, /**< option defines the maximum attempts of search request retransmission */
MBUS_OPTION_PURGE_FIRST_FRAME /**< option controls the echo cancelation for mbus_recv_frame */
} mbus_context_option;
diff --git a/mbus/mbus-protocol.c b/mbus/mbus-protocol.c
index 8ec3130..27b0354 100755
--- a/mbus/mbus-protocol.c
+++ b/mbus/mbus-protocol.c
@@ -480,60 +480,105 @@ mbus_data_bcd_decode(unsigned char *bcd_data, size_t bcd_data_size)
///
//------------------------------------------------------------------------------
int
-mbus_data_int_decode(unsigned char *int_data, size_t int_data_size)
+mbus_data_int_decode(unsigned char *int_data, size_t int_data_size, int *value)
{
- int val = 0;
size_t i;
+ int neg;
+ *value = 0;
- if (int_data)
+ if (!int_data || (int_data_size < 1))
{
- for (i = int_data_size; i > 0; i--)
- {
- val = (val << 8) + int_data[i-1];
- }
-
- return val;
+ return -1;
+ }
+
+ neg = int_data[int_data_size-1] & 0x80;
+
+ for (i = int_data_size; i > 0; i--)
+ {
+ if (neg)
+ {
+ *value = (*value << 8) + (int_data[i-1] ^ 0xFF);
+ }
+ else
+ {
+ *value = (*value << 8) + int_data[i-1];
+ }
}
- return -1;
+ if (neg)
+ {
+ *value = *value * -1 - 1;
+ }
+
+ return 0;
}
-long
-mbus_data_long_decode(unsigned char *int_data, size_t int_data_size)
+int
+mbus_data_long_decode(unsigned char *int_data, size_t int_data_size, long *value)
{
- long val = 0;
size_t i;
+ int neg;
+ *value = 0;
- if (int_data)
+ if (!int_data || (int_data_size < 1))
{
- for (i = int_data_size; i > 0; i--)
- {
- val = (val << 8) + int_data[i-1];
- }
-
- return val;
+ return -1;
+ }
+
+ neg = int_data[int_data_size-1] & 0x80;
+
+ for (i = int_data_size; i > 0; i--)
+ {
+ if (neg)
+ {
+ *value = (*value << 8) + (int_data[i-1] ^ 0xFF);
+ }
+ else
+ {
+ *value = (*value << 8) + int_data[i-1];
+ }
}
- return -1;
+ if (neg)
+ {
+ *value = *value * -1 - 1;
+ }
+
+ return 0;
}
-long long
-mbus_data_long_long_decode(unsigned char *int_data, size_t int_data_size)
+int
+mbus_data_long_long_decode(unsigned char *int_data, size_t int_data_size, long long *value)
{
- long long val = 0;
size_t i;
+ int neg;
+ *value = 0;
- if (int_data)
+ if (!int_data || (int_data_size < 1))
{
- for (i = int_data_size; i > 0; i--)
- {
- val = (val << 8) + int_data[i-1];
- }
-
- return val;
+ return -1;
+ }
+
+ neg = int_data[int_data_size-1] & 0x80;
+
+ for (i = int_data_size; i > 0; i--)
+ {
+ if (neg)
+ {
+ *value = (*value << 8) + (int_data[i-1] ^ 0xFF);
+ }
+ else
+ {
+ *value = (*value << 8) + int_data[i-1];
+ }
}
- return -1;
+ if (neg)
+ {
+ *value = *value * -1 - 1;
+ }
+
+ return 0;
}
//------------------------------------------------------------------------------
@@ -742,7 +787,7 @@ mbus_decode_manufacturer(unsigned char byte1, unsigned char byte2)
m_str[0] = byte1;
m_str[1] = byte2;
- m_id = mbus_data_int_decode(m_str, 2);
+ mbus_data_int_decode(m_str, 2, &m_id);
m_str[0] = (char)(((m_id>>10) & 0x001F) + 64);
m_str[1] = (char)(((m_id>>5) & 0x001F) + 64);
@@ -830,6 +875,15 @@ mbus_data_product_name(mbus_data_variable_header *header)
break;
}
}
+ else if (manufacturer == MBUS_VARIABLE_DATA_MAN_GMC)
+ {
+ switch (header->version)
+ {
+ case 0xE6:
+ strcpy(buff,"GMC-I A230 EMMOD 206");
+ break;
+ }
+ }
else if (manufacturer == MBUS_VARIABLE_DATA_MAN_SLB)
{
switch (header->version)
@@ -869,6 +923,15 @@ mbus_data_product_name(mbus_data_variable_header *header)
break;
}
}
+ else if (manufacturer == MBUS_VARIABLE_DATA_MAN_RAM)
+ {
+ switch (header->version)
+ {
+ case 0x03:
+ strcpy(buff, "Rossweiner ETK/ETW Modularis");
+ break;
+ }
+ }
else if (manufacturer == MBUS_VARIABLE_DATA_MAN_RKE)
{
switch (header->version)
@@ -1540,14 +1603,14 @@ mbus_unit_prefix(int exp)
}
//------------------------------------------------------------------------------
-/// Look up the data lenght from a VIF field in the data record.
+/// Look up the data length from a DIF field in the data record.
///
/// See the table on page 41 the M-BUS specification.
//------------------------------------------------------------------------------
unsigned char
mbus_dif_datalength_lookup(unsigned char dif)
{
- switch (dif&0x0F)
+ switch (dif & MBUS_DATA_RECORD_DIF_MASK_DATA)
{
case 0x0:
return 0;
@@ -2149,16 +2212,16 @@ mbus_data_record_decode(mbus_data_record *record)
if (record)
{
- int val;
- float val3;
- long long val4;
+ int int_val;
+ float float_val;
+ long long long_long_val;
struct tm time;
// ignore extension bit
vif = (record->drh.vib.vif & MBUS_DIB_VIF_WITHOUT_EXTENSION);
vife = (record->drh.vib.vife[0] & MBUS_DIB_VIF_WITHOUT_EXTENSION);
- switch (record->drh.dib.dif & 0x0F)
+ switch (record->drh.dib.dif & MBUS_DATA_RECORD_DIF_MASK_DATA)
{
case 0x00: // no data
@@ -2168,9 +2231,9 @@ mbus_data_record_decode(mbus_data_record *record)
case 0x01: // 1 byte integer (8 bit)
- val = mbus_data_int_decode(record->data, 1);
+ mbus_data_int_decode(record->data, 1, &int_val);
- snprintf(buff, sizeof(buff), "%d", val);
+ snprintf(buff, sizeof(buff), "%d", int_val);
if (debug)
printf("%s: DIF 0x%.2x was decoded using 1 byte integer\n", __PRETTY_FUNCTION__, record->drh.dib.dif);
@@ -2191,8 +2254,8 @@ mbus_data_record_decode(mbus_data_record *record)
}
else // 2 byte integer
{
- val = mbus_data_int_decode(record->data, 2);
- snprintf(buff, sizeof(buff), "%d", val);
+ mbus_data_int_decode(record->data, 2, &int_val);
+ snprintf(buff, sizeof(buff), "%d", int_val);
if (debug)
printf("%s: DIF 0x%.2x was decoded using 2 byte integer\n", __PRETTY_FUNCTION__, record->drh.dib.dif);
@@ -2202,9 +2265,9 @@ mbus_data_record_decode(mbus_data_record *record)
case 0x03: // 3 byte integer (24 bit)
- val = mbus_data_int_decode(record->data, 3);
+ mbus_data_int_decode(record->data, 3, &int_val);
- snprintf(buff, sizeof(buff), "%d", val);
+ snprintf(buff, sizeof(buff), "%d", int_val);
if (debug)
printf("%s: DIF 0x%.2x was decoded using 3 byte integer\n", __PRETTY_FUNCTION__, record->drh.dib.dif);
@@ -2231,8 +2294,8 @@ mbus_data_record_decode(mbus_data_record *record)
}
else // 4 byte integer
{
- val = mbus_data_int_decode(record->data, 4);
- snprintf(buff, sizeof(buff), "%d", val);
+ mbus_data_int_decode(record->data, 4, &int_val);
+ snprintf(buff, sizeof(buff), "%d", int_val);
}
if (debug)
@@ -2242,9 +2305,9 @@ mbus_data_record_decode(mbus_data_record *record)
case 0x05: // 4 Byte Real (32 bit)
- val3 = mbus_data_float_decode(record->data);
+ float_val = mbus_data_float_decode(record->data);
- snprintf(buff, sizeof(buff), "%f", val3);
+ snprintf(buff, sizeof(buff), "%f", float_val);
if (debug)
printf("%s: DIF 0x%.2x was decoded using 4 byte Real\n", __PRETTY_FUNCTION__, record->drh.dib.dif);
@@ -2253,9 +2316,9 @@ mbus_data_record_decode(mbus_data_record *record)
case 0x06: // 6 byte integer (48 bit)
- val4 = mbus_data_long_long_decode(record->data, 6);
+ mbus_data_long_long_decode(record->data, 6, &long_long_val);
- snprintf(buff, sizeof(buff), "%lld", val4);
+ 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);
@@ -2264,9 +2327,9 @@ mbus_data_record_decode(mbus_data_record *record)
case 0x07: // 8 byte integer (64 bit)
- val4 = mbus_data_long_long_decode(record->data, 8);
+ mbus_data_long_long_decode(record->data, 8, &long_long_val);
- snprintf(buff, sizeof(buff), "%lld", val4);
+ snprintf(buff, sizeof(buff), "%lld", long_long_val);
if (debug)
printf("%s: DIF 0x%.2x was decoded using 8 byte integer\n", __PRETTY_FUNCTION__, record->drh.dib.dif);
@@ -2277,8 +2340,8 @@ mbus_data_record_decode(mbus_data_record *record)
case 0x09: // 2 digit BCD (8 bit)
- val = (int)mbus_data_bcd_decode(record->data, 1);
- snprintf(buff, sizeof(buff), "%d", val);
+ int_val = (int)mbus_data_bcd_decode(record->data, 1);
+ snprintf(buff, sizeof(buff), "%d", int_val);
if (debug)
printf("%s: DIF 0x%.2x was decoded using 2 digit BCD\n", __PRETTY_FUNCTION__, record->drh.dib.dif);
@@ -2287,8 +2350,8 @@ mbus_data_record_decode(mbus_data_record *record)
case 0x0A: // 4 digit BCD (16 bit)
- val = (int)mbus_data_bcd_decode(record->data, 2);
- snprintf(buff, sizeof(buff), "%d", val);
+ int_val = (int)mbus_data_bcd_decode(record->data, 2);
+ snprintf(buff, sizeof(buff), "%d", int_val);
if (debug)
printf("%s: DIF 0x%.2x was decoded using 4 digit BCD\n", __PRETTY_FUNCTION__, record->drh.dib.dif);
@@ -2297,8 +2360,8 @@ mbus_data_record_decode(mbus_data_record *record)
case 0x0B: // 6 digit BCD (24 bit)
- val = (int)mbus_data_bcd_decode(record->data, 3);
- snprintf(buff, sizeof(buff), "%d", val);
+ int_val = (int)mbus_data_bcd_decode(record->data, 3);
+ snprintf(buff, sizeof(buff), "%d", int_val);
if (debug)
printf("%s: DIF 0x%.2x was decoded using 6 digit BCD\n", __PRETTY_FUNCTION__, record->drh.dib.dif);
@@ -2307,8 +2370,8 @@ mbus_data_record_decode(mbus_data_record *record)
case 0x0C: // 8 digit BCD (32 bit)
- val = (int)mbus_data_bcd_decode(record->data, 4);
- snprintf(buff, sizeof(buff), "%d", val);
+ int_val = (int)mbus_data_bcd_decode(record->data, 4);
+ snprintf(buff, sizeof(buff), "%d", int_val);
if (debug)
printf("%s: DIF 0x%.2x was decoded using 8 digit BCD\n", __PRETTY_FUNCTION__, record->drh.dib.dif);
@@ -2317,8 +2380,8 @@ mbus_data_record_decode(mbus_data_record *record)
case 0x0E: // 12 digit BCD (48 bit)
- val4 = mbus_data_bcd_decode(record->data, 6);
- snprintf(buff, sizeof(buff), "%lld", val4);
+ long_long_val = mbus_data_bcd_decode(record->data, 6);
+ snprintf(buff, sizeof(buff), "%lld", long_long_val);
if (debug)
printf("%s: DIF 0x%.2x was decoded using 12 digit BCD\n", __PRETTY_FUNCTION__, record->drh.dib.dif);
@@ -2385,6 +2448,78 @@ mbus_data_record_value(mbus_data_record *record)
return NULL;
}
+//------------------------------------------------------------------------------
+/// Return the storage number for a variable-length data record
+//------------------------------------------------------------------------------
+long mbus_data_record_storage_number(mbus_data_record *record)
+{
+ int bit_index;
+ long result = 0;
+ int i;
+
+ if (record)
+ {
+ result |= (record->drh.dib.dif & MBUS_DATA_RECORD_DIF_MASK_STORAGE_NO) >> 6;
+ bit_index++;
+
+ for (i=0; idrh.dib.ndife; i++)
+ {
+ result |= (record->drh.dib.dife[i] & MBUS_DATA_RECORD_DIFE_MASK_STORAGE_NO) << bit_index;
+ bit_index += 4;
+ }
+
+ return result;
+ }
+
+ return 0;
+}
+
+//------------------------------------------------------------------------------
+/// Return the tariff for a variable-length data record
+//------------------------------------------------------------------------------
+long mbus_data_record_tariff(mbus_data_record *record)
+{
+ int bit_index;
+ long result = 0;
+ int i;
+
+ if (record && (record->drh.dib.ndife > 0))
+ {
+ for (i=0; idrh.dib.ndife; i++)
+ {
+ result |= ((record->drh.dib.dife[i] & MBUS_DATA_RECORD_DIFE_MASK_TARIFF) >> 4) << bit_index;
+ bit_index += 2;
+ }
+
+ return result;
+ }
+
+ return -1;
+}
+
+//------------------------------------------------------------------------------
+/// Return device unit for a variable-length data record
+//------------------------------------------------------------------------------
+int mbus_data_record_device(mbus_data_record *record)
+{
+ int bit_index;
+ int result = 0;
+ int i;
+
+ if (record && (record->drh.dib.ndife > 0))
+ {
+ for (i=0; idrh.dib.ndife; i++)
+ {
+ result |= ((record->drh.dib.dife[i] & MBUS_DATA_RECORD_DIFE_MASK_DEVICE) >> 6) << bit_index;
+ bit_index++;
+ }
+
+ return result;
+ }
+
+ return -1;
+}
+
//------------------------------------------------------------------------------
/// Return a string containing the function description
//------------------------------------------------------------------------------
@@ -2827,7 +2962,7 @@ mbus_data_variable_parse(mbus_frame *frame, mbus_data_variable *data)
}
// re-calculate data length, if of variable length type
- if ((record->drh.dib.dif & 0x0F) == 0x0D) // flag for variable length data
+ if ((record->drh.dib.dif & MBUS_DATA_RECORD_DIF_MASK_DATA) == 0x0D) // flag for variable length data
{
if(frame->data[i] <= 0xBF)
record->data_len = frame->data[i++];
@@ -3270,10 +3405,11 @@ mbus_data_variable_print(mbus_data_variable *data)
for (record = data->record; record; record = record->next)
{
// DIF
- printf("DIF = %.2X\n", record->drh.dib.dif);
- printf("DIF.Extension = %s\n", (record->drh.dib.dif & MBUS_DIB_DIF_EXTENSION_BIT) ? "Yes":"No");
- printf("DIF.Function = %s\n", (record->drh.dib.dif & 0x30) ? "Minimum value" : "Instantaneous value" );
- printf("DIF.Data = %.2X\n", record->drh.dib.dif & 0x0F);
+ printf("DIF = %.2X\n", record->drh.dib.dif);
+ printf("DIF.Extension = %s\n", (record->drh.dib.dif & MBUS_DIB_DIF_EXTENSION_BIT) ? "Yes":"No");
+ printf("DIF.StorageNumber = %d\n", (record->drh.dib.dif & MBUS_DATA_RECORD_DIF_MASK_STORAGE_NO) >> 6);
+ printf("DIF.Function = %s\n", (record->drh.dib.dif & 0x30) ? "Minimum value" : "Instantaneous value" );
+ printf("DIF.Data = %.2X\n", record->drh.dib.dif & 0x0F);
// VENDOR SPECIFIC
if ((record->drh.dib.dif == MBUS_DIB_DIF_MANUFACTURER_SPECIFIC) ||
@@ -3301,10 +3437,11 @@ mbus_data_variable_print(mbus_data_variable *data)
{
unsigned char dife = record->drh.dib.dife[j];
- printf("DIFE[%zd] = %.2X\n", j, dife);
- printf("DIFE[%zd].Extension = %s\n", j, (dife & MBUS_DIB_DIF_EXTENSION_BIT) ? "Yes" : "No");
- printf("DIFE[%zd].Function = %s\n", j, (dife & 0x30) ? "Minimum value" : "Instantaneous value" );
- printf("DIFE[%zd].Data = %.2X\n", j, dife & 0x0F);
+ printf("DIFE[%zd] = %.2X\n", j, dife);
+ printf("DIFE[%zd].Extension = %s\n", j, (dife & MBUS_DATA_RECORD_DIFE_MASK_EXTENSION) ? "Yes" : "No");
+ printf("DIFE[%zd].Device = %d\n", j, (dife & MBUS_DATA_RECORD_DIFE_MASK_DEVICE) >> 6 );
+ printf("DIFE[%zd].Tariff = %d\n", j, (dife & MBUS_DATA_RECORD_DIFE_MASK_TARIFF) >> 4 );
+ printf("DIFE[%zd].StorageNumber = %.2X\n", j, dife & MBUS_DATA_RECORD_DIFE_MASK_STORAGE_NO);
}
// VIF
@@ -3332,6 +3469,8 @@ mbus_data_variable_print(mbus_data_variable *data)
int
mbus_data_fixed_print(mbus_data_fixed *data)
{
+ int val;
+
if (data)
{
printf("%s: ID = %d\n", __PRETTY_FUNCTION__, (int)mbus_data_bcd_decode(data->id_bcd, 4));
@@ -3343,23 +3482,26 @@ 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 = %d\n", __PRETTY_FUNCTION__, (int)mbus_data_bcd_decode(data->cnt1_val, 4));
+ val = mbus_data_bcd_decode(data->cnt1_val, 4);
}
else
{
- printf("%s: Counter1 = %d\n", __PRETTY_FUNCTION__, mbus_data_int_decode(data->cnt1_val, 4));
+ mbus_data_int_decode(data->cnt1_val, 4, &val);
+
}
+ printf("%s: Counter1 = %d\n", __PRETTY_FUNCTION__, val);
printf("%s: Medium2 = %s\n", __PRETTY_FUNCTION__, mbus_data_fixed_medium(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 = %d\n", __PRETTY_FUNCTION__, (int)mbus_data_bcd_decode(data->cnt2_val, 4));
+ val = mbus_data_bcd_decode(data->cnt2_val, 4);
}
else
{
- printf("%s: Counter2 = %d\n", __PRETTY_FUNCTION__, mbus_data_int_decode(data->cnt2_val, 4));
+ mbus_data_int_decode(data->cnt2_val, 4, &val);
}
+ printf("%s: Counter2 = %d\n", __PRETTY_FUNCTION__, val);
}
return -1;
@@ -3515,6 +3657,7 @@ mbus_data_variable_record_xml(mbus_data_record *record, int record_cnt, int fram
size_t len = 0;
struct tm * timeinfo;
char timestamp[21];
+ long tariff;
if (record)
{
@@ -3545,6 +3688,19 @@ mbus_data_variable_record_xml(mbus_data_record *record, int record_cnt, int fram
mbus_str_xml_encode(str_encoded, mbus_data_record_function(record), sizeof(str_encoded));
len += snprintf(&buff[len], sizeof(buff) - len,
" %s\n", str_encoded);
+
+ len += snprintf(&buff[len], sizeof(buff) - len,
+ " %ld\n",
+ mbus_data_record_storage_number(record));
+
+
+ if ((tariff = mbus_data_record_tariff(record)) >= 0)
+ {
+ len += snprintf(&buff[len], sizeof(buff) - len, " %ld\n",
+ tariff);
+ len += snprintf(&buff[len], sizeof(buff) - len, " %d\n",
+ mbus_data_record_device(record));
+ }
mbus_str_xml_encode(str_encoded, mbus_data_record_unit(record), sizeof(str_encoded));
len += snprintf(&buff[len], sizeof(buff) - len,
@@ -3629,6 +3785,7 @@ mbus_data_fixed_xml(mbus_data_fixed *data)
char *buff = NULL;
char str_encoded[256];
size_t len = 0, buff_size = 8192;
+ int val;
if (data)
{
@@ -3658,12 +3815,14 @@ mbus_data_fixed_xml(mbus_data_fixed *data)
len += snprintf(&buff[len], buff_size - len, " %s\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, " %d\n", (int)mbus_data_bcd_decode(data->cnt1_val, 4));
+ val = mbus_data_bcd_decode(data->cnt1_val, 4);
}
else
{
- len += snprintf(&buff[len], buff_size - len, " %d\n", mbus_data_int_decode(data->cnt1_val, 4));
+ mbus_data_int_decode(data->cnt1_val, 4, &val);
}
+ len += snprintf(&buff[len], buff_size - len, " %d\n", val);
+
len += snprintf(&buff[len], buff_size - len, " \n\n");
len += snprintf(&buff[len], buff_size - len, " \n");
@@ -3675,12 +3834,14 @@ mbus_data_fixed_xml(mbus_data_fixed *data)
len += snprintf(&buff[len], buff_size - len, " %s\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, " %d\n", (int)mbus_data_bcd_decode(data->cnt2_val, 4));
+ val = mbus_data_bcd_decode(data->cnt2_val, 4);
}
else
{
- len += snprintf(&buff[len], buff_size - len, " %d\n", mbus_data_int_decode(data->cnt2_val, 4));
+ mbus_data_int_decode(data->cnt2_val, 4, &val);
}
+ len += snprintf(&buff[len], buff_size - len, " %d\n", val);
+
len += snprintf(&buff[len], buff_size - len, " \n\n");
len += snprintf(&buff[len], buff_size - len, "\n");
diff --git a/mbus/mbus-protocol.h b/mbus/mbus-protocol.h
index 8c8edde..c63e089 100755
--- a/mbus/mbus-protocol.h
+++ b/mbus/mbus-protocol.h
@@ -445,6 +445,11 @@ typedef struct _mbus_data_secondary_address {
#define MBUS_DATA_RECORD_DIF_MASK_EXTENTION 0x80
#define MBUS_DATA_RECORD_DIF_MASK_NON_DATA 0xF0
+#define MBUS_DATA_RECORD_DIFE_MASK_STORAGE_NO 0x0F
+#define MBUS_DATA_RECORD_DIFE_MASK_TARIFF 0x30
+#define MBUS_DATA_RECORD_DIFE_MASK_DEVICE 0x40
+#define MBUS_DATA_RECORD_DIFE_MASK_EXTENSION 0x80
+
//
// GENERAL APPLICATION ERRORS
//
@@ -494,6 +499,7 @@ typedef struct _mbus_data_secondary_address {
#define MBUS_VARIABLE_DATA_MAN_ELS 0x1593
#define MBUS_VARIABLE_DATA_MAN_ELV 0x1596
#define MBUS_VARIABLE_DATA_MAN_EMH 0x15A8
+#define MBUS_VARIABLE_DATA_MAN_GMC 0x1DA3
#define MBUS_VARIABLE_DATA_MAN_HYD 0x2324
#define MBUS_VARIABLE_DATA_MAN_KAM 0x2C2D
#define MBUS_VARIABLE_DATA_MAN_LSE 0x3265
@@ -501,6 +507,7 @@ typedef struct _mbus_data_secondary_address {
#define MBUS_VARIABLE_DATA_MAN_NZR 0x3B52
#define MBUS_VARIABLE_DATA_MAN_PAD 0x4024
#define MBUS_VARIABLE_DATA_MAN_QDS 0x4493
+#define MBUS_VARIABLE_DATA_MAN_RAM 0x482D
#define MBUS_VARIABLE_DATA_MAN_RKE 0x4965
#define MBUS_VARIABLE_DATA_MAN_SEN 0x4CAE
#define MBUS_VARIABLE_DATA_MAN_SLB 0x4D82
@@ -559,6 +566,9 @@ int mbus_frame_internal_pack(mbus_frame *frame, mbus_frame_data *frame_data);
//
const char *mbus_data_record_function(mbus_data_record *record);
const char *mbus_data_fixed_function(int status);
+long mbus_data_record_storage_number(mbus_data_record *record);
+long mbus_data_record_tariff(mbus_data_record *record);
+int mbus_data_record_device(mbus_data_record *record);
//
// M-Bus frame data struct access/write functions
@@ -613,9 +623,9 @@ 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);
-int mbus_data_int_decode(unsigned char *int_data, size_t int_data_size);
-long mbus_data_long_decode(unsigned char *int_data, size_t int_data_size);
-long long mbus_data_long_long_decode(unsigned char *int_data, size_t int_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);
float mbus_data_float_decode(unsigned char *float_data);
diff --git a/test/test-frames/Elster-F2.xml b/test/test-frames/Elster-F2.xml
index 7fea60b..e020ffb 100644
--- a/test/test-frames/Elster-F2.xml
+++ b/test/test-frames/Elster-F2.xml
@@ -13,78 +13,97 @@
Instantaneous value
+ 0
Energy (kWh)
5272
Instantaneous value
+ 0
Volume (1e-2 m^3)
120427
Instantaneous value
+ 0
+ 0
+ 1
Volume (1e-2 m^3)
91769
Instantaneous value
+ 0
Flow temperature (deg C)
28
Instantaneous value
+ 0
Return temperature (deg C)
34
Instantaneous value
+ 0
Temperature Difference (1e-1 deg C)
0
Instantaneous value
+ 0
On time (hours)
41393
Instantaneous value
+ 0
Operating time (hours)
41393
Instantaneous value
+ 0
Volume flow (m m^3/h)
0
Instantaneous value
+ 0
Power (10 W)
0
Instantaneous value
+ 0
Time Point (time & date)
2013-06-29T12:12:00
Instantaneous value
+ 0
+ 0
+ 1
Units for H.C.A.
0
Instantaneous value
+ 0
+ 0
+ 2
Units for H.C.A.
0
diff --git a/test/test-frames/abb_f95.xml b/test/test-frames/abb_f95.xml
index 2db805d..7c29d3a 100644
--- a/test/test-frames/abb_f95.xml
+++ b/test/test-frames/abb_f95.xml
@@ -91,6 +91,7 @@
Instantaneous value
+ 0
Operating time (hours)
86553
diff --git a/test/test-frames/allmess_cf50.xml b/test/test-frames/allmess_cf50.xml
index c16a2c1..612bdd9 100644
--- a/test/test-frames/allmess_cf50.xml
+++ b/test/test-frames/allmess_cf50.xml
@@ -13,54 +13,63 @@
Instantaneous value
+ 0
Energy (10 kWh)
0
Instantaneous value
+ 0
Volume (1e-1 m^3)
3
Instantaneous value
+ 0
Power (kW)
0
Instantaneous value
+ 0
Volume flow (m m^3/h)
0
Instantaneous value
+ 0
Flow temperature (1e-1 deg C)
1288
Instantaneous value
+ 0
Return temperature (1e-1 deg C)
516
Instantaneous value
+ 0
Temperature Difference (1e-2 deg C)
7723
Instantaneous value
+ 0
Time Point (date)
2012-01-12
Instantaneous value
+ 0
Operating time (days)
3383
diff --git a/test/test-frames/electricity-meter-1.xml b/test/test-frames/electricity-meter-1.xml
index 10c83d5..8d25237 100644
--- a/test/test-frames/electricity-meter-1.xml
+++ b/test/test-frames/electricity-meter-1.xml
@@ -13,120 +13,156 @@
Instantaneous value
+ 0
+ 1
+ 0
Energy (10 Wh)
1252
Instantaneous value
+ 2
+ 1
+ 0
Energy (10 Wh)
1252
Instantaneous value
+ 0
+ 2
+ 0
Energy (10 Wh)
1774433
Instantaneous value
+ 2
+ 2
+ 0
Energy (10 Wh)
1774433
Instantaneous value
+ 0
V
237
Instantaneous value
+ 0
1e-1 A
32
Instantaneous value
+ 0
Power (10 W)
79
Instantaneous value
+ 0
+ 0
+ 1
Power (10 W)
- 65518
+ -18
Instantaneous value
+ 0
V
231
Instantaneous value
+ 0
1e-1 A
35
Instantaneous value
+ 0
Power (10 W)
81
Instantaneous value
+ 0
+ 0
+ 1
Power (10 W)
- 65521
+ -15
Instantaneous value
+ 0
V
228
Instantaneous value
+ 0
1e-1 A
69
Instantaneous value
+ 0
Power (10 W)
160
Instantaneous value
+ 0
+ 0
+ 1
Power (10 W)
- 65504
+ -32
Instantaneous value
+ 0
Manufacturer specific
0
Instantaneous value
+ 0
Power (10 W)
320
Instantaneous value
+ 0
+ 0
+ 1
Power (10 W)
- 65471
+ -65
Instantaneous value
+ 0
Manufacturer specific
4
diff --git a/test/test-frames/electricity-meter-2.xml b/test/test-frames/electricity-meter-2.xml
index ff07f0d..1045933 100644
--- a/test/test-frames/electricity-meter-2.xml
+++ b/test/test-frames/electricity-meter-2.xml
@@ -13,120 +13,156 @@
Instantaneous value
+ 0
+ 1
+ 0
Energy (10 Wh)
254
Instantaneous value
+ 2
+ 1
+ 0
Energy (10 Wh)
254
Instantaneous value
+ 0
+ 2
+ 0
Energy (10 Wh)
444128
Instantaneous value
+ 2
+ 2
+ 0
Energy (10 Wh)
444128
Instantaneous value
+ 0
V
233
Instantaneous value
+ 0
1e-1 A
1
Instantaneous value
+ 0
Power (10 W)
0
Instantaneous value
+ 0
+ 0
+ 1
Power (10 W)
0
Instantaneous value
+ 0
V
234
Instantaneous value
+ 0
1e-1 A
0
Instantaneous value
+ 0
Power (10 W)
0
Instantaneous value
+ 0
+ 0
+ 1
Power (10 W)
0
Instantaneous value
+ 0
V
235
Instantaneous value
+ 0
1e-1 A
1
Instantaneous value
+ 0
Power (10 W)
0
Instantaneous value
+ 0
+ 0
+ 1
Power (10 W)
0
Instantaneous value
+ 0
Manufacturer specific
0
Instantaneous value
+ 0
Power (10 W)
0
Instantaneous value
+ 0
+ 0
+ 1
Power (10 W)
0
Instantaneous value
+ 0
Manufacturer specific
4
diff --git a/test/test-frames/els_tmpa_telegramm1.xml b/test/test-frames/els_tmpa_telegramm1.xml
index d0b4fa9..4a22242 100644
--- a/test/test-frames/els_tmpa_telegramm1.xml
+++ b/test/test-frames/els_tmpa_telegramm1.xml
@@ -13,30 +13,35 @@
Instantaneous value
+ 0
Volume (m m^3)
1234567
Instantaneous value
+ 0
Time Point (time & date)
2007-02-06T13:58:00
Instantaneous value
+ 1
Time Point (date)
2007-01-01
Instantaneous value
+ 1
Volume (m m^3)
456951
Instantaneous value
+ 1
Time Point (date)
2008-01-01
diff --git a/test/test-frames/elv_temp_humid.xml b/test/test-frames/elv_temp_humid.xml
index c02fcc3..6ebb57a 100644
--- a/test/test-frames/elv_temp_humid.xml
+++ b/test/test-frames/elv_temp_humid.xml
@@ -13,72 +13,86 @@
Instantaneous value
+ 0
Digital input (binary)
0
Instantaneous value
+ 0
1e-2 %RH
4564
Minimum value
+ 0
1e-2 %RH
4552
Maximum value
+ 0
1e-2 %RH
5812
Instantaneous value
+ 0
External temperature (1e-2 deg C)
2256
Minimum value
+ 0
External temperature (1e-2 deg C)
2160
Maximum value
+ 0
External temperature (1e-2 deg C)
2339
Instantaneous value
+ 0
Averaging Duration (hours)
24
Instantaneous value
+ 1
External temperature (1e-2 deg C)
2276
Instantaneous value
+ 2
+ 0
+ 0
External temperature (1e-2 deg C)
2269
Instantaneous value
+ 0
Fabrication number
54000834
Instantaneous value
+ 0
Software version
262144
diff --git a/test/test-frames/emh_diz.xml b/test/test-frames/emh_diz.xml
index 78117ee..46dc68a 100644
--- a/test/test-frames/emh_diz.xml
+++ b/test/test-frames/emh_diz.xml
@@ -13,18 +13,25 @@
Instantaneous value
+ 0
+ 1
+ 0
Energy (10 Wh)
409
Instantaneous value
+ 1
+ 0
+ 0
Power (1e-1 W)
0
Instantaneous value
+ 0
Error flags
0
diff --git a/test/test-frames/gmc_emmod206.hex b/test/test-frames/gmc_emmod206.hex
new file mode 100644
index 0000000..0c9cdd0
--- /dev/null
+++ b/test/test-frames/gmc_emmod206.hex
@@ -0,0 +1 @@
+68 91 91 68 08 03 72 78 56 34 12 A3 1D E6 02 02 00 00 00 82 40 FD 48 60 03 82 80 40 FD 48 BF 03 82 C0 40 FD 48 20 04 82 40 FD 59 BD 03 82 80 40 FD 59 1F 04 82 C0 40 FD 59 7E 04 82 40 2B E0 00 82 40 2B 36 FF 84 10 04 94 28 00 00 84 20 04 98 3A 00 00 84 50 04 BF 4E 00 00 84 60 04 A8 61 00 00 84 90 40 04 8B 75 00 00 84 A0 40 04 B8 88 00 00 84 D0 40 04 2D 9D 00 00 84 E0 40 04 C8 AF 00 00 82 41 2B E0 00 82 42 2B 00 00 82 43 2B 00 00 82 44 2B CA 00 42 16
diff --git a/test/test-frames/gmc_emmod206.xml b/test/test-frames/gmc_emmod206.xml
new file mode 100644
index 0000000..ab18ed2
--- /dev/null
+++ b/test/test-frames/gmc_emmod206.xml
@@ -0,0 +1,194 @@
+
+
+
+ 12345678
+ GMC
+ 230
+ GMC-I A230 EMMOD 206
+ Electricity
+ 2
+ 00
+ 0000
+
+
+
+ Instantaneous value
+ 0
+ 0
+ 1
+ 1e-1 V
+ 864
+
+
+
+ Instantaneous value
+ 0
+ 0
+ 2
+ 1e-1 V
+ 959
+
+
+
+ Instantaneous value
+ 0
+ 0
+ 3
+ 1e-1 V
+ 1056
+
+
+
+ Instantaneous value
+ 0
+ 0
+ 1
+ m A
+ 957
+
+
+
+ Instantaneous value
+ 0
+ 0
+ 2
+ m A
+ 1055
+
+
+
+ Instantaneous value
+ 0
+ 0
+ 3
+ m A
+ 1150
+
+
+
+ Instantaneous value
+ 0
+ 0
+ 1
+ Power (W)
+ 224
+
+
+
+ Instantaneous value
+ 0
+ 0
+ 1
+ Power (W)
+ -202
+
+
+
+ Instantaneous value
+ 0
+ 1
+ 0
+ Energy (10 Wh)
+ 10388
+
+
+
+ Instantaneous value
+ 0
+ 2
+ 0
+ Energy (10 Wh)
+ 15000
+
+
+
+ Instantaneous value
+ 0
+ 1
+ 1
+ Energy (10 Wh)
+ 20159
+
+
+
+ Instantaneous value
+ 0
+ 2
+ 1
+ Energy (10 Wh)
+ 25000
+
+
+
+ Instantaneous value
+ 0
+ 1
+ 2
+ Energy (10 Wh)
+ 30091
+
+
+
+ Instantaneous value
+ 0
+ 2
+ 2
+ Energy (10 Wh)
+ 35000
+
+
+
+ Instantaneous value
+ 0
+ 1
+ 3
+ Energy (10 Wh)
+ 40237
+
+
+
+ Instantaneous value
+ 0
+ 2
+ 3
+ Energy (10 Wh)
+ 45000
+
+
+
+ Instantaneous value
+ 2
+ 0
+ 1
+ Power (W)
+ 224
+
+
+
+ Instantaneous value
+ 4
+ 0
+ 1
+ Power (W)
+ 0
+
+
+
+ Instantaneous value
+ 6
+ 0
+ 1
+ Power (W)
+ 0
+
+
+
+ Instantaneous value
+ 8
+ 0
+ 1
+ Power (W)
+ 202
+
+
+
diff --git a/test/test-frames/kamstrup_multical_601.xml b/test/test-frames/kamstrup_multical_601.xml
index 856f7dc..5b74577 100644
--- a/test/test-frames/kamstrup_multical_601.xml
+++ b/test/test-frames/kamstrup_multical_601.xml
@@ -13,162 +13,209 @@
Instantaneous value
+ 0
Fabrication number
6855817
Instantaneous value
+ 0
Energy (kWh)
37351
Instantaneous value
+ 0
Volume (1e-2 m^3)
56108
Instantaneous value
+ 0
On time (hours)
985
Instantaneous value
+ 0
Flow temperature (1e-2 deg C)
10169
Instantaneous value
+ 0
Return temperature (1e-2 deg C)
4616
Instantaneous value
+ 0
Temperature Difference (1e-2 deg C)
5553
Instantaneous value
+ 0
Power (100 W)
347
Maximum value
+ 0
Power (100 W)
448
Instantaneous value
+ 0
Volume flow (m m^3/h)
543
Maximum value
+ 0
Volume flow (m m^3/h)
628
Instantaneous value
+ 0
+ 1
+ 0
Energy (kWh)
0
Instantaneous value
+ 0
+ 2
+ 0
Energy (kWh)
0
Instantaneous value
+ 0
+ 0
+ 1
Volume (1e-2 m^3)
0
Instantaneous value
+ 0
+ 0
+ 2
Volume (1e-2 m^3)
0
Instantaneous value
+ 0
+ 0
+ 3
Energy (kWh)
0
Instantaneous value
+ 0
Time Point (time & date)
2011-01-05T15:26:00
Instantaneous value
+ 1
Energy (kWh)
33361
Instantaneous value
+ 1
Volume (1e-2 m^3)
50098
Maximum value
+ 1
Power (100 W)
550
Maximum value
+ 1
Volume flow (m m^3/h)
1027
Instantaneous value
+ 1
+ 1
+ 0
Energy (kWh)
0
Instantaneous value
+ 1
+ 2
+ 0
Energy (kWh)
0
Instantaneous value
+ 1
+ 0
+ 1
Volume (1e-2 m^3)
0
Instantaneous value
+ 1
+ 0
+ 2
Volume (1e-2 m^3)
0
Instantaneous value
+ 1
+ 0
+ 3
Energy (kWh)
0
Instantaneous value
+ 1
Time Point (date)
2010-12-31
diff --git a/test/test-frames/manual_frame3.xml b/test/test-frames/manual_frame3.xml
index 2b1211e..34a51b5 100644
--- a/test/test-frames/manual_frame3.xml
+++ b/test/test-frames/manual_frame3.xml
@@ -13,18 +13,25 @@
Instantaneous value
+ 0
Volume (m m^3)
12565
Maximum value
+ 5
+ 0
+ 0
Volume flow (m m^3/h)
113
Instantaneous value
+ 0
+ 2
+ 1
Energy (10 Wh)
21837
diff --git a/test/test-frames/manual_frame7.xml b/test/test-frames/manual_frame7.xml
index dc166e3..a3c2dad 100644
--- a/test/test-frames/manual_frame7.xml
+++ b/test/test-frames/manual_frame7.xml
@@ -13,6 +13,7 @@
Instantaneous value
+ 0
Fabrication number
1020304
diff --git a/test/test-frames/nzr_dhz_5_63.xml b/test/test-frames/nzr_dhz_5_63.xml
index f7120a3..40b91b2 100644
--- a/test/test-frames/nzr_dhz_5_63.xml
+++ b/test/test-frames/nzr_dhz_5_63.xml
@@ -13,36 +13,42 @@
Instantaneous value
+ 0
Energy (Wh)
1274
Instantaneous value
+ 0
Energy (Wh)
1274
Instantaneous value
+ 0
1e-1 V
2372
Instantaneous value
+ 0
1e-1 A
0
Instantaneous value
+ 0
Power (W)
0
Instantaneous value
+ 0
Fabrication number
30100608
diff --git a/test/test-frames/wmbus-converted.xml b/test/test-frames/wmbus-converted.xml
index aefeabd..e7f0686 100644
--- a/test/test-frames/wmbus-converted.xml
+++ b/test/test-frames/wmbus-converted.xml
@@ -13,6 +13,7 @@
Instantaneous value
+ 0
Energy (Wh)
5000