Merge pull request #26 from lategoodbye/master

Fixed parsing with custom VIFE
This commit is contained in:
Robert Johansson 2012-10-25 07:39:08 -07:00
commit ee6241c331
5 changed files with 232 additions and 15 deletions

View File

@ -17,6 +17,7 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <math.h>
#define MBUS_ERROR(...) fprintf (stderr, __VA_ARGS__) #define MBUS_ERROR(...) fprintf (stderr, __VA_ARGS__)
@ -1024,12 +1025,13 @@ mbus_vib_unit_normalize(mbus_value_information_block *vib, double value, char **
return -1; return -1;
} }
} }
else if (vib->vif == 0x7C) else if ((vib->vif == 0x7C) ||
(vib->vif == 0xFC))
{ {
// custom VIF // custom VIF
*unit_out = strdup("-"); *unit_out = strdup("-");
*quantity_out = strdup(vib->custom_vif); *quantity_out = strdup(vib->custom_vif);
*value_out = 0.0; *value_out = value;
} }
else else
{ {
@ -1042,6 +1044,37 @@ mbus_vib_unit_normalize(mbus_value_information_block *vib, double value, char **
} }
} }
if ((vib->vif & MBUS_DIB_VIF_EXTENSION_BIT) &&
(vib->vif != 0xFD) &&
(vib->vif != 0xFB)) /* codes for VIF extention: see table 8.4.5 */
{
int code = (vib->vif) & 0x7f;
switch (code)
{
case 0x70:
case 0x71:
case 0x72:
case 0x73:
case 0x74:
case 0x75:
case 0x76:
case 0x77: /* Multiplicative correction factor: 10^nnn-6 */
*value_out *= pow(10.0, (vib->vife[0] & 0x07) - 6);
break;
case 0x78:
case 0x79:
case 0x7A:
case 0x7B: /* Additive correction constant: 10^nn-3 unit of VIF (offset) */
*value_out += pow(10.0, (vib->vife[0] & 0x03) - 3);
break;
case 0x7D: /* Multiplicative correction factor: 10^3 */
*value_out *= 1000.0;
break;
}
}
return 0; return 0;
} }
@ -1658,6 +1691,12 @@ mbus_sendrecv_request(mbus_handle *handle, int address, mbus_frame *reply, int m
mbus_frame *frame, *next_frame; mbus_frame *frame, *next_frame;
int frame_count = 0, result; int frame_count = 0, result;
if (handle == NULL)
{
MBUS_ERROR("%s: Invalid M-Bus handle for request.\n", __PRETTY_FUNCTION__);
return 1;
}
frame = mbus_frame_new(MBUS_FRAME_TYPE_SHORT); frame = mbus_frame_new(MBUS_FRAME_TYPE_SHORT);
if (frame == NULL) if (frame == NULL)

View File

@ -817,6 +817,36 @@ mbus_data_product_name(mbus_data_variable_header *header)
break; break;
} }
} }
else if (manufacturer == MBUS_VARIABLE_DATA_MAN_ELV)
{
switch (header->version)
{
case 0x14:
case 0x15:
case 0x16:
case 0x17:
case 0x18:
case 0x19:
case 0x1A:
case 0x1B:
case 0x1C:
case 0x1D:
strcpy(buff, "Elvaco CMa10");
break;
case 0x32:
case 0x33:
case 0x34:
case 0x35:
case 0x36:
case 0x37:
case 0x38:
case 0x39:
case 0x3A:
case 0x3B:
strcpy(buff,"Elvaco CMa11");
break;
}
}
else if (manufacturer == MBUS_VARIABLE_DATA_MAN_SLB) else if (manufacturer == MBUS_VARIABLE_DATA_MAN_SLB)
{ {
switch (header->version) switch (header->version)
@ -2055,12 +2085,22 @@ mbus_vib_unit_lookup(mbus_value_information_block *vib)
// VIFE = E001 0001 Customer // VIFE = E001 0001 Customer
snprintf(buff, sizeof(buff), "Customer"); snprintf(buff, sizeof(buff), "Customer");
} }
else if (vib->vife[0] == 0x9) else if (vib->vife[0] == 0x1A)
{
// VIFE = E001 1010 Digital output (binary)
snprintf(buff, sizeof(buff), "Digital output (binary)");
}
else if (vib->vife[0] == 0x1B)
{
// VIFE = E001 1011 Digital input (binary)
snprintf(buff, sizeof(buff), "Digital input (binary)");
}
else if (vib->vife[0] == 0x09)
{ {
// VIFE = E001 0110 Password // VIFE = E001 0110 Password
snprintf(buff, sizeof(buff), "Password"); snprintf(buff, sizeof(buff), "Password");
} }
else if (vib->vife[0] == 0x0b) else if (vib->vife[0] == 0x0B)
{ {
// VIFE = E000 1011 Parameter set identification // VIFE = E000 1011 Parameter set identification
snprintf(buff, sizeof(buff), "Parameter set identification"); snprintf(buff, sizeof(buff), "Parameter set identification");
@ -2094,6 +2134,13 @@ mbus_vib_unit_lookup(mbus_value_information_block *vib)
snprintf(buff, sizeof(buff), "%s", vib->custom_vif); snprintf(buff, sizeof(buff), "%s", vib->custom_vif);
return buff; return buff;
} }
else if (vib->vif == 0xFC && (vib->vife[0] & 0x78) == 0x70)
{
// custom VIF
n = (vib->vife[0] & 0x07);
snprintf(buff, sizeof(buff), "%s %s", mbus_unit_prefix(n-6), vib->custom_vif);
return buff;
}
return mbus_vif_unit_lookup(vib->vif); // no extention, use VIF return mbus_vif_unit_lookup(vib->vif); // no extention, use VIF
} }
@ -2676,21 +2723,30 @@ mbus_data_variable_parse(mbus_frame *frame, mbus_data_variable *data)
// read and parse VIB (= VIF + VIFE) // read and parse VIB (= VIF + VIFE)
// VIF // VIF
record->drh.vib.vif = frame->data[i]; record->drh.vib.vif = frame->data[i++];
if (record->drh.vib.vif == 0x7C) if ((record->drh.vib.vif & 0x7F) == 0x7C)
{ {
// variable length VIF in ASCII format // variable length VIF in ASCII format
int var_vif_len; int var_vif_len;
i++;
var_vif_len = frame->data[i++]; var_vif_len = frame->data[i++];
if (i + var_vif_len > frame->data_size)
{
mbus_data_record_free(record);
return -1;
}
mbus_data_str_decode(record->drh.vib.custom_vif, &(frame->data[i]), var_vif_len); mbus_data_str_decode(record->drh.vib.custom_vif, &(frame->data[i]), var_vif_len);
i += var_vif_len; i += var_vif_len;
} }
else
{
// VIFE // VIFE
record->drh.vib.nvife = 0; record->drh.vib.nvife = 0;
if (record->drh.vib.vif & MBUS_DIB_VIF_EXTENSION_BIT)
{
record->drh.vib.vife[0] = frame->data[i];
record->drh.vib.nvife++;
while (frame->data[i] & MBUS_DIB_VIF_EXTENSION_BIT && while (frame->data[i] & MBUS_DIB_VIF_EXTENSION_BIT &&
record->drh.vib.nvife < NITEMS(record->drh.vib.vife)) record->drh.vib.nvife < NITEMS(record->drh.vib.vife))
{ {
@ -3180,6 +3236,22 @@ mbus_data_variable_print(mbus_data_variable *data)
printf("DIFE[%zd].Data = %.2X\n", j, dife & 0x0F); printf("DIFE[%zd].Data = %.2X\n", j, dife & 0x0F);
} }
// VIF
printf("VIF = %.2X\n", record->drh.vib.vif);
printf("VIF.Extension = %s\n", (record->drh.vib.vif & MBUS_DIB_VIF_EXTENSION_BIT) ? "Yes":"No");
printf("VIF.Value = %.2X\n", record->drh.vib.vif & 0x7F);
// VIFE
for (j = 0; j < record->drh.vib.nvife; j++)
{
u_char vife = record->drh.vib.vife[j];
printf("VIFE[%zd] = %.2X\n", j, vife);
printf("VIFE[%zd].Extension = %s\n", j, (vife & MBUS_DIB_VIF_EXTENSION_BIT) ? "Yes" : "No");
printf("VIFE[%zd].Value = %.2X\n", j, vife & 0x7F);
}
printf("\n");
} }
} }

View File

@ -476,6 +476,7 @@ typedef struct _mbus_data_secondary_address {
#define MBUS_VARIABLE_DATA_MAN_AMT 0x05B4 #define MBUS_VARIABLE_DATA_MAN_AMT 0x05B4
#define MBUS_VARIABLE_DATA_MAN_EFE 0x14C5 #define MBUS_VARIABLE_DATA_MAN_EFE 0x14C5
#define MBUS_VARIABLE_DATA_MAN_ELS 0x1593 #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_EMH 0x15A8
#define MBUS_VARIABLE_DATA_MAN_HYD 0x2324 #define MBUS_VARIABLE_DATA_MAN_HYD 0x2324
#define MBUS_VARIABLE_DATA_MAN_KAM 0x2C2D #define MBUS_VARIABLE_DATA_MAN_KAM 0x2C2D

View File

@ -0,0 +1 @@
68 53 53 68 08 05 72 34 08 00 54 96 15 32 00 F2 00 00 00 01 FD 1B 00 02 FC 03 48 52 25 74 D4 11 22 FC 03 48 52 25 74 C8 11 12 FC 03 48 52 25 74 B4 16 02 65 D0 08 22 65 70 08 12 65 23 09 01 72 18 42 65 E4 08 82 01 65 DD 08 0C 78 34 08 00 54 03 FD 0F 00 00 04 1F 5D 16

View File

@ -0,0 +1,104 @@
<MBusData>
<SlaveInformation>
<Id>54000834</Id>
<Manufacturer>ELV</Manufacturer>
<Version>50</Version>
<ProductName></ProductName>
<Medium>Other</Medium>
<AccessNumber>242</AccessNumber>
<Status>00</Status>
<Signature>0000</Signature>
</SlaveInformation>
<DataRecord id="0">
<Function>Instantaneous value</Function>
<Unit>Digital input (binary)</Unit>
<Value>0</Value>
<Timestamp>1970-01-01T00:00:00</Timestamp>
</DataRecord>
<DataRecord id="1">
<Function>Instantaneous value</Function>
<Unit>1e-2 %RH</Unit>
<Value>4564</Value>
<Timestamp>1970-01-01T00:00:00</Timestamp>
</DataRecord>
<DataRecord id="2">
<Function>Minimum value</Function>
<Unit>1e-2 %RH</Unit>
<Value>4552</Value>
<Timestamp>1970-01-01T00:00:00</Timestamp>
</DataRecord>
<DataRecord id="3">
<Function>Maximum value</Function>
<Unit>1e-2 %RH</Unit>
<Value>5812</Value>
<Timestamp>1970-01-01T00:00:00</Timestamp>
</DataRecord>
<DataRecord id="4">
<Function>Instantaneous value</Function>
<Unit>External temperature (1e-2 deg C)</Unit>
<Value>2256</Value>
<Timestamp>1970-01-01T00:00:00</Timestamp>
</DataRecord>
<DataRecord id="5">
<Function>Minimum value</Function>
<Unit>External temperature (1e-2 deg C)</Unit>
<Value>2160</Value>
<Timestamp>1970-01-01T00:00:00</Timestamp>
</DataRecord>
<DataRecord id="6">
<Function>Maximum value</Function>
<Unit>External temperature (1e-2 deg C)</Unit>
<Value>2339</Value>
<Timestamp>1970-01-01T00:00:00</Timestamp>
</DataRecord>
<DataRecord id="7">
<Function>Instantaneous value</Function>
<Unit>Averaging Duration (hours)</Unit>
<Value>24</Value>
<Timestamp>1970-01-01T00:00:00</Timestamp>
</DataRecord>
<DataRecord id="8">
<Function>Instantaneous value</Function>
<Unit>External temperature (1e-2 deg C)</Unit>
<Value>2276</Value>
<Timestamp>1970-01-01T00:00:00</Timestamp>
</DataRecord>
<DataRecord id="9">
<Function>Instantaneous value</Function>
<Unit>External temperature (1e-2 deg C)</Unit>
<Value>2269</Value>
<Timestamp>1970-01-01T00:00:00</Timestamp>
</DataRecord>
<DataRecord id="10">
<Function>Instantaneous value</Function>
<Unit>Fabrication number</Unit>
<Value>54000834</Value>
<Timestamp>1970-01-01T00:00:00</Timestamp>
</DataRecord>
<DataRecord id="11">
<Function>Instantaneous value</Function>
<Unit>Software version</Unit>
<Value>262144</Value>
<Timestamp>1970-01-01T00:00:00</Timestamp>
</DataRecord>
<DataRecord id="12">
<Function>More records follow</Function>
<Value></Value>
<Timestamp>1970-01-01T00:00:00</Timestamp>
</DataRecord>
</MBusData>