Compare commits
10 Commits
serial-tim
...
negative-b
Author | SHA1 | Date | |
---|---|---|---|
36a85d3737 | |||
2f9fa5ccc8 | |||
027f6fb689 | |||
de4a899b9d | |||
2a2fbc372a | |||
6d3bb00d97 | |||
84c43fe7a3 | |||
73d58a9f7d | |||
ab8919136d | |||
2680079db4 |
1
.gitignore
vendored
1
.gitignore
vendored
@ -52,6 +52,7 @@ bin/mbus-serial-request-data-multi-reply
|
||||
bin/mbus-serial-scan
|
||||
bin/mbus-serial-scan-secondary
|
||||
bin/mbus-serial-select-secondary
|
||||
bin/mbus-serial-set-address
|
||||
bin/mbus-serial-switch-baudrate
|
||||
bin/mbus-tcp-raw-send
|
||||
bin/mbus-tcp-request-data
|
||||
|
16
COPYING
16
COPYING
@ -20,19 +20,5 @@ Contributers:
|
||||
* Pelle van der Heide
|
||||
* James Michael DuPont
|
||||
* Uwe Grohnwaldt
|
||||
* Markus Bergkvist
|
||||
|
||||
LICENSE (the BSD license):
|
||||
|
||||
Copyright (c) 2010-2012, Raditex Control AB
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the Raditex Control AB nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
* Markus Bergkvist
|
||||
|
||||
|
29
LICENSE
Normal file
29
LICENSE
Normal file
@ -0,0 +1,29 @@
|
||||
BSD 3-Clause License
|
||||
|
||||
Copyright (c) 2010-2012, Raditex Control AB
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
@ -17,7 +17,8 @@ bin_PROGRAMS = mbus-tcp-scan mbus-tcp-request-data mbus-tcp-request-data-multi
|
||||
mbus-tcp-select-secondary mbus-tcp-scan-secondary \
|
||||
mbus-serial-scan mbus-serial-request-data mbus-serial-request-data-multi-reply \
|
||||
mbus-serial-select-secondary mbus-serial-scan-secondary \
|
||||
mbus-serial-switch-baudrate mbus-tcp-raw-send mbus-tcp-application-reset
|
||||
mbus-serial-switch-baudrate mbus-tcp-raw-send mbus-tcp-application-reset \
|
||||
mbus-serial-set-address
|
||||
|
||||
# tcp
|
||||
mbus_tcp_scan_LDFLAGS = -L$(top_builddir)/mbus
|
||||
@ -73,6 +74,10 @@ mbus_serial_switch_baudrate_LDFLAGS = -L$(top_builddir)/mbus
|
||||
mbus_serial_switch_baudrate_LDADD = -lmbus -lm
|
||||
mbus_serial_switch_baudrate_SOURCES = mbus-serial-switch-baudrate.c
|
||||
|
||||
mbus_serial_set_address_LDFLAGS = -L$(top_builddir)/mbus
|
||||
mbus_serial_set_address_LDADD = -lmbus -lm
|
||||
mbus_serial_set_address_SOURCES = mbus-serial-set-address.c
|
||||
|
||||
# man pages
|
||||
dist_man_MANS = libmbus.1 \
|
||||
mbus-tcp-scan.1 \
|
||||
|
@ -10,6 +10,8 @@ the communication with M-Bus devices.
|
||||
|
||||
B<mbus-serial-switch-baudrate> [-b BAUDRATE] device address target-baudrate
|
||||
|
||||
B<mbus-serial-set-address> [-d] [-b BAUDRATE] device mbus-address new-primary-address
|
||||
|
||||
B<mbus-serial-scan> [-d] [-b BAUDRATE] [-r RETRIES] device
|
||||
|
||||
B<mbus-tcp-scan> [-d] [-r RETRIES] host port
|
||||
|
2
bin/mbus-serial-set-address.1
Normal file
2
bin/mbus-serial-set-address.1
Normal file
@ -0,0 +1,2 @@
|
||||
.so man1/libmbus.1
|
||||
|
229
bin/mbus-serial-set-address.c
Normal file
229
bin/mbus-serial-set-address.c
Normal file
@ -0,0 +1,229 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// Copyright (C) 2011, Robert Johansson, Raditex AB
|
||||
// All rights reserved.
|
||||
//
|
||||
// rSCADA
|
||||
// http://www.rSCADA.se
|
||||
// info@rscada.se
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <mbus/mbus.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// set primary address
|
||||
//------------------------------------------------------------------------------
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
mbus_handle *handle = NULL;
|
||||
mbus_frame reply;
|
||||
char *device, *old_address_str, *xml_result;
|
||||
int old_address, new_address;
|
||||
long baudrate = 9600;
|
||||
int ret;
|
||||
|
||||
if (argc == 4)
|
||||
{
|
||||
device = argv[1];
|
||||
old_address_str = argv[2];
|
||||
new_address = atoi(argv[3]);
|
||||
}
|
||||
else if (argc == 5 && strcmp(argv[1], "-d") == 0)
|
||||
{
|
||||
device = argv[2];
|
||||
old_address_str = argv[3];
|
||||
new_address = atoi(argv[4]);
|
||||
debug = 1;
|
||||
}
|
||||
else if (argc == 6 && strcmp(argv[1], "-b") == 0)
|
||||
{
|
||||
baudrate = atol(argv[2]);
|
||||
device = argv[3];
|
||||
old_address_str = argv[4];
|
||||
new_address = atoi(argv[5]);
|
||||
}
|
||||
else if (argc == 7 && strcmp(argv[1], "-d") == 0 && strcmp(argv[2], "-b") == 0)
|
||||
{
|
||||
baudrate = atol(argv[3]);
|
||||
device = argv[4];
|
||||
old_address_str = argv[5];
|
||||
new_address = atoi(argv[6]);
|
||||
debug = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "usage: %s [-d] [-b BAUDRATE] device mbus-address new-primary-address\n", argv[0]);
|
||||
fprintf(stderr, " optional flag -d for debug printout\n");
|
||||
fprintf(stderr, " optional flag -b for selecting baudrate\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (mbus_is_primary_address(new_address) == 0)
|
||||
{
|
||||
fprintf(stderr, "Invalid new primary address\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (new_address)
|
||||
{
|
||||
case MBUS_ADDRESS_NETWORK_LAYER:
|
||||
case MBUS_ADDRESS_BROADCAST_REPLY:
|
||||
case MBUS_ADDRESS_BROADCAST_NOREPLY:
|
||||
fprintf(stderr, "Invalid new primary address\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((handle = mbus_context_serial(device)) == NULL)
|
||||
{
|
||||
fprintf(stderr, "Could not initialize M-Bus context: %s\n", mbus_error_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (debug)
|
||||
{
|
||||
mbus_register_send_event(handle, &mbus_dump_send_event);
|
||||
mbus_register_recv_event(handle, &mbus_dump_recv_event);
|
||||
}
|
||||
|
||||
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_send_ping_frame(handle, new_address, 0) == -1)
|
||||
{
|
||||
fprintf(stderr, "Verification failed. Could not send ping frame: %s\n", mbus_error_str());
|
||||
mbus_disconnect(handle);
|
||||
mbus_context_free(handle);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (mbus_recv_frame(handle, &reply) != MBUS_RECV_RESULT_TIMEOUT)
|
||||
{
|
||||
fprintf(stderr, "Verification failed. Got a response from new address\n");
|
||||
mbus_disconnect(handle);
|
||||
mbus_context_free(handle);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (mbus_is_secondary_address(old_address_str))
|
||||
{
|
||||
// secondary addressing
|
||||
|
||||
ret = mbus_select_secondary_address(handle, old_address_str);
|
||||
|
||||
if (ret == MBUS_PROBE_COLLISION)
|
||||
{
|
||||
fprintf(stderr, "%s: Error: The address mask [%s] matches more than one device.\n", __PRETTY_FUNCTION__, old_address_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__, old_address_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__, old_address_str);
|
||||
mbus_disconnect(handle);
|
||||
mbus_context_free(handle);
|
||||
return 1;
|
||||
}
|
||||
// else MBUS_PROBE_SINGLE
|
||||
|
||||
old_address = MBUS_ADDRESS_NETWORK_LAYER;
|
||||
}
|
||||
else
|
||||
{
|
||||
// primary addressing
|
||||
old_address = atoi(old_address_str);
|
||||
}
|
||||
|
||||
if (mbus_set_primary_address(handle, old_address, new_address) == -1)
|
||||
{
|
||||
fprintf(stderr, "Failed to send set primary address frame: %s\n", mbus_error_str());
|
||||
mbus_disconnect(handle);
|
||||
mbus_context_free(handle);
|
||||
return 1;
|
||||
}
|
||||
|
||||
memset(&reply, 0, sizeof(mbus_frame));
|
||||
ret = mbus_recv_frame(handle, &reply);
|
||||
|
||||
if (ret == MBUS_RECV_RESULT_TIMEOUT)
|
||||
{
|
||||
fprintf(stderr, "No reply from device\n");
|
||||
mbus_disconnect(handle);
|
||||
mbus_context_free(handle);
|
||||
return 1;
|
||||
}
|
||||
else if (mbus_frame_type(&reply) != MBUS_FRAME_TYPE_ACK)
|
||||
{
|
||||
fprintf(stderr, "Unknown reply:\n");
|
||||
mbus_frame_print(&reply);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Set primary address of device to %d\n", new_address);
|
||||
}
|
||||
|
||||
mbus_disconnect(handle);
|
||||
mbus_context_free(handle);
|
||||
return 0;
|
||||
}
|
@ -154,17 +154,17 @@ mbus_variable_vif vif_table[] = {
|
||||
{ 0x56, 1.0e3, "kg/h", "Mass flow" },
|
||||
{ 0x57, 1.0e4, "kg/h", "Mass flow" },
|
||||
|
||||
/* E101 10nn Flow Temperature <EFBFBD>C (0.001<EFBFBD>C to 1<EFBFBD>C) */
|
||||
{ 0x58, 1.0e-3, "<EFBFBD>C", "Flow temperature" },
|
||||
{ 0x59, 1.0e-2, "<EFBFBD>C", "Flow temperature" },
|
||||
{ 0x5A, 1.0e-1, "<EFBFBD>C", "Flow temperature" },
|
||||
{ 0x5B, 1.0e0, "<EFBFBD>C", "Flow temperature" },
|
||||
/* E101 10nn Flow Temperature °C (0.001°C to 1°C) */
|
||||
{ 0x58, 1.0e-3, "°C", "Flow temperature" },
|
||||
{ 0x59, 1.0e-2, "°C", "Flow temperature" },
|
||||
{ 0x5A, 1.0e-1, "°C", "Flow temperature" },
|
||||
{ 0x5B, 1.0e0, "°C", "Flow temperature" },
|
||||
|
||||
/* E101 11nn Return Temperature <EFBFBD>C (0.001<EFBFBD>C to 1<EFBFBD>C) */
|
||||
{ 0x5C, 1.0e-3, "<EFBFBD>C", "Return temperature" },
|
||||
{ 0x5D, 1.0e-2, "<EFBFBD>C", "Return temperature" },
|
||||
{ 0x5E, 1.0e-1, "<EFBFBD>C", "Return temperature" },
|
||||
{ 0x5F, 1.0e0, "<EFBFBD>C", "Return temperature" },
|
||||
/* E101 11nn Return Temperature °C (0.001°C to 1°C) */
|
||||
{ 0x5C, 1.0e-3, "°C", "Return temperature" },
|
||||
{ 0x5D, 1.0e-2, "°C", "Return temperature" },
|
||||
{ 0x5E, 1.0e-1, "°C", "Return temperature" },
|
||||
{ 0x5F, 1.0e0, "°C", "Return temperature" },
|
||||
|
||||
/* E110 00nn Temperature Difference K (mK to K) */
|
||||
{ 0x60, 1.0e-3, "K", "Temperature difference" },
|
||||
@ -172,11 +172,11 @@ mbus_variable_vif vif_table[] = {
|
||||
{ 0x62, 1.0e-1, "K", "Temperature difference" },
|
||||
{ 0x63, 1.0e0, "K", "Temperature difference" },
|
||||
|
||||
/* E110 01nn External Temperature <EFBFBD>C (0.001<EFBFBD>C to 1<EFBFBD>C) */
|
||||
{ 0x64, 1.0e-3, "<EFBFBD>C", "External temperature" },
|
||||
{ 0x65, 1.0e-2, "<EFBFBD>C", "External temperature" },
|
||||
{ 0x66, 1.0e-1, "<EFBFBD>C", "External temperature" },
|
||||
{ 0x67, 1.0e0, "<EFBFBD>C", "External temperature" },
|
||||
/* E110 01nn External Temperature °C (0.001°C to 1°C) */
|
||||
{ 0x64, 1.0e-3, "°C", "External temperature" },
|
||||
{ 0x65, 1.0e-2, "°C", "External temperature" },
|
||||
{ 0x66, 1.0e-1, "°C", "External temperature" },
|
||||
{ 0x67, 1.0e0, "°C", "External temperature" },
|
||||
|
||||
/* E110 10nn Pressure bar (1mbar to 1000mbar) */
|
||||
{ 0x68, 1.0e-3, "bar", "Pressure" },
|
||||
@ -608,29 +608,29 @@ mbus_variable_vif vif_table[] = {
|
||||
{ 0x256, 1.0e0, "Reserved", "Reserved" },
|
||||
{ 0x257, 1.0e0, "Reserved", "Reserved" },
|
||||
|
||||
/* E101 10nn Flow Temperature 10(nn-3) <EFBFBD>F 0.001<EFBFBD>F to 1<EFBFBD>F */
|
||||
{ 0x258, 1.0e-3, "<EFBFBD>F", "Flow temperature" },
|
||||
{ 0x259, 1.0e-2, "<EFBFBD>F", "Flow temperature" },
|
||||
{ 0x25A, 1.0e-1, "<EFBFBD>F", "Flow temperature" },
|
||||
{ 0x25B, 1.0e0, "<EFBFBD>F", "Flow temperature" },
|
||||
/* 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) <EFBFBD>F 0.001<EFBFBD>F to 1<EFBFBD>F */
|
||||
{ 0x25C, 1.0e-3, "<EFBFBD>F", "Return temperature" },
|
||||
{ 0x25D, 1.0e-2, "<EFBFBD>F", "Return temperature" },
|
||||
{ 0x25E, 1.0e-1, "<EFBFBD>F", "Return temperature" },
|
||||
{ 0x25F, 1.0e0, "<EFBFBD>F", "Return 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) <EFBFBD>F 0.001<EFBFBD>F to 1<EFBFBD>F */
|
||||
{ 0x260, 1.0e-3, "<EFBFBD>F", "Temperature difference" },
|
||||
{ 0x261, 1.0e-2, "<EFBFBD>F", "Temperature difference" },
|
||||
{ 0x262, 1.0e-1, "<EFBFBD>F", "Temperature difference" },
|
||||
{ 0x263, 1.0e0, "<EFBFBD>F", "Temperature difference" },
|
||||
/* 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) <EFBFBD>F 0.001<EFBFBD>F to 1<EFBFBD>F */
|
||||
{ 0x264, 1.0e-3, "<EFBFBD>F", "External temperature" },
|
||||
{ 0x265, 1.0e-2, "<EFBFBD>F", "External temperature" },
|
||||
{ 0x266, 1.0e-1, "<EFBFBD>F", "External temperature" },
|
||||
{ 0x267, 1.0e0, "<EFBFBD>F", "External temperature" },
|
||||
/* 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" },
|
||||
@ -642,19 +642,19 @@ mbus_variable_vif vif_table[] = {
|
||||
{ 0x26E, 1.0e0, "Reserved", "Reserved" },
|
||||
{ 0x26F, 1.0e0, "Reserved", "Reserved" },
|
||||
|
||||
/* E111 00nn Cold / Warm Temperature Limit 10(nn-3) <EFBFBD>F 0.001<EFBFBD>F to 1<EFBFBD>F */
|
||||
{ 0x270, 1.0e-3, "<EFBFBD>F", "Cold / Warm Temperature Limit" },
|
||||
{ 0x271, 1.0e-2, "<EFBFBD>F", "Cold / Warm Temperature Limit" },
|
||||
{ 0x272, 1.0e-1, "<EFBFBD>F", "Cold / Warm Temperature Limit" },
|
||||
{ 0x273, 1.0e0, "<EFBFBD>F", "Cold / Warm Temperature Limit" },
|
||||
/* E111 00nn Cold / Warm Temperature Limit 10(nn-3) °F 0.001°F to 1°F */
|
||||
{ 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) <EFBFBD>C 0.001<EFBFBD>C to 1<EFBFBD>C */
|
||||
{ 0x274, 1.0e-3, "<EFBFBD>C", "Cold / Warm Temperature Limit" },
|
||||
{ 0x275, 1.0e-2, "<EFBFBD>C", "Cold / Warm Temperature Limit" },
|
||||
{ 0x276, 1.0e-1, "<EFBFBD>C", "Cold / Warm Temperature Limit" },
|
||||
{ 0x277, 1.0e0, "<EFBFBD>C", "Cold / Warm Temperature Limit" },
|
||||
/* E111 01nn Cold / Warm Temperature Limit 10(nn-3) °C 0.001°C to 1°C */
|
||||
{ 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 <EFBFBD> 10(nnn-3) W 0.001W to 10000W */
|
||||
/* E111 1nnn cumul. count max power § 10(nnn-3) W 0.001W to 10000W */
|
||||
{ 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" },
|
||||
@ -730,7 +730,7 @@ mbus_variable_vif fixed_table[] = {
|
||||
{ 0x36, 1.0e1, "m^3/h", "Volume flow" },
|
||||
{ 0x37, 1.0e2, "m^3/h", "Volume flow" },
|
||||
|
||||
{ 0x38, 1.0e-3, "<EFBFBD>C", "Temperature" },
|
||||
{ 0x38, 1.0e-3, "°C", "Temperature" },
|
||||
|
||||
{ 0x39, 1.0e0, "Units for H.C.A.", "H.C.A." },
|
||||
|
||||
@ -886,7 +886,7 @@ int mbus_variable_value_decode(mbus_data_record *record, double *value_out_real,
|
||||
else // normal integer
|
||||
{
|
||||
result = mbus_data_int_decode(record->data, 2, &value_out_int);
|
||||
*value_out_real = value_out_int;
|
||||
*value_out_real = value_out_int;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -904,12 +904,12 @@ int mbus_variable_value_decode(mbus_data_record *record, double *value_out_real,
|
||||
((record->drh.vib.vif == 0xFD) && (vife == 0x70)))
|
||||
{
|
||||
mbus_data_tm_decode(&time, record->data, 4);
|
||||
if ((*value_out_str = (char*) malloc(20)) == NULL)
|
||||
if ((*value_out_str = (char*) malloc(21)) == NULL)
|
||||
{
|
||||
MBUS_ERROR("Unable to allocate memory");
|
||||
return -1;
|
||||
}
|
||||
*value_out_str_size = snprintf(*value_out_str, 20, "%04d-%02d-%02dT%02d:%02d:%02d",
|
||||
*value_out_str_size = snprintf(*value_out_str, 21, "%04d-%02d-%02dT%02d:%02d:%02dZ",
|
||||
(time.tm_year + 1900),
|
||||
(time.tm_mon + 1),
|
||||
time.tm_mday,
|
||||
@ -921,7 +921,7 @@ int mbus_variable_value_decode(mbus_data_record *record, double *value_out_real,
|
||||
else // normal integer
|
||||
{
|
||||
result = mbus_data_int_decode(record->data, 4, &value_out_int);
|
||||
*value_out_real = value_out_int;
|
||||
*value_out_real = value_out_int;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -939,12 +939,12 @@ int mbus_variable_value_decode(mbus_data_record *record, double *value_out_real,
|
||||
((record->drh.vib.vif == 0xFD) && (vife == 0x70)))
|
||||
{
|
||||
mbus_data_tm_decode(&time, record->data, 6);
|
||||
if ((*value_out_str = (char*) malloc(20)) == NULL)
|
||||
if ((*value_out_str = (char*) malloc(21)) == NULL)
|
||||
{
|
||||
MBUS_ERROR("Unable to allocate memory");
|
||||
return -1;
|
||||
}
|
||||
*value_out_str_size = snprintf(*value_out_str, 20, "%04d-%02d-%02dT%02d:%02d:%02d",
|
||||
*value_out_str_size = snprintf(*value_out_str, 21, "%04d-%02d-%02dT%02d:%02d:%02dZ",
|
||||
(time.tm_year + 1900),
|
||||
(time.tm_mon + 1),
|
||||
time.tm_mday,
|
||||
@ -1286,7 +1286,7 @@ 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);
|
||||
@ -1981,6 +1981,33 @@ mbus_send_user_data_frame(mbus_handle * handle, int address, const unsigned char
|
||||
return retval;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// send a request from master to slave in order to change the primary address
|
||||
//------------------------------------------------------------------------------
|
||||
int
|
||||
mbus_set_primary_address(mbus_handle * handle, int old_address, int new_address)
|
||||
{
|
||||
/* primary address record, see chapter 6.4.2 */
|
||||
unsigned char buffer[3] = { 0x01, 0x7A, new_address };
|
||||
|
||||
if (mbus_is_primary_address(new_address) == 0)
|
||||
{
|
||||
MBUS_ERROR("%s: invalid address %d\n", __PRETTY_FUNCTION__, new_address);
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (new_address)
|
||||
{
|
||||
case MBUS_ADDRESS_NETWORK_LAYER:
|
||||
case MBUS_ADDRESS_BROADCAST_REPLY:
|
||||
case MBUS_ADDRESS_BROADCAST_NOREPLY:
|
||||
MBUS_ERROR("%s: invalid address %d\n", __PRETTY_FUNCTION__, new_address);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return mbus_send_user_data_frame(handle, old_address, buffer, sizeof(buffer));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// send a request from master to slave and collect the reply (replies)
|
||||
// from the slave.
|
||||
@ -2304,7 +2331,7 @@ mbus_probe_secondary_address(mbus_handle *handle, const char *mask, char *matchi
|
||||
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("Failed to generate secondary address from M-Bus reply frame: %s\n",
|
||||
mbus_error_str());
|
||||
return MBUS_PROBE_NOTHING;
|
||||
}
|
||||
|
@ -307,6 +307,17 @@ int mbus_send_request_frame(mbus_handle * handle, int address);
|
||||
*/
|
||||
int mbus_send_user_data_frame(mbus_handle * handle, int address, const unsigned char *data, size_t data_size);
|
||||
|
||||
/**
|
||||
* Sends frame to change primary address of given slave using "unified" handle
|
||||
*
|
||||
* @param handle Initialized handle
|
||||
* @param old_address Old Address (0-255)
|
||||
* @param new_address New Address (0-250)
|
||||
*
|
||||
* @return Zero when successful.
|
||||
*/
|
||||
int mbus_set_primary_address(mbus_handle * handle, int old_address, int new_address);
|
||||
|
||||
/**
|
||||
* Sends a request and read replies until no more records available
|
||||
* or limit is reached.
|
||||
|
@ -461,9 +461,9 @@ mbus_data_bcd_encode(unsigned char *bcd_data, size_t bcd_data_size, int value)
|
||||
int v0, v1, v2, x1, x2;
|
||||
size_t i;
|
||||
|
||||
if (bcd_data && bcd_data_size && (value >= 0))
|
||||
if (bcd_data && bcd_data_size)
|
||||
{
|
||||
v2 = value;
|
||||
v2 = abs(value);
|
||||
|
||||
for (i = 0; i < bcd_data_size; i++)
|
||||
{
|
||||
@ -477,6 +477,11 @@ mbus_data_bcd_encode(unsigned char *bcd_data, size_t bcd_data_size, int value)
|
||||
bcd_data[bcd_data_size-1-i] = (x2 << 4) | x1;
|
||||
}
|
||||
|
||||
if (value < 0)
|
||||
{
|
||||
bcd_data[bcd_data_size-1] |= 0xF0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -498,8 +503,20 @@ mbus_data_bcd_decode(unsigned char *bcd_data, size_t bcd_data_size)
|
||||
{
|
||||
for (i = bcd_data_size; i > 0; i--)
|
||||
{
|
||||
val = (val * 10) + ((bcd_data[i-1]>>4) & 0xF);
|
||||
val = (val * 10) + ( bcd_data[i-1] & 0xF);
|
||||
val = (val * 10);
|
||||
|
||||
if (bcd_data[i-1]>>4 < 0xA)
|
||||
{
|
||||
val += ((bcd_data[i-1]>>4) & 0xF);
|
||||
}
|
||||
|
||||
val = (val * 10) + ( bcd_data[i-1] & 0xF);
|
||||
}
|
||||
|
||||
// hex code Fh in the MSD position signals a negative BCD number
|
||||
if (bcd_data[bcd_data_size-1]>>4 == 0xF)
|
||||
{
|
||||
val *= -1;
|
||||
}
|
||||
|
||||
return val;
|
||||
@ -1088,6 +1105,9 @@ mbus_data_product_name(mbus_data_variable_header *header)
|
||||
case 0x28:
|
||||
strcpy(buff,"ABB F95 Typ US770");
|
||||
break;
|
||||
case 0x2F:
|
||||
strcpy(buff,"Hydrometer Sharky 775");
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (manufacturer == mbus_manufacturer_id("JAN"))
|
||||
@ -3739,7 +3759,7 @@ mbus_hex_dump(const char *label, const char *buff, size_t len)
|
||||
{
|
||||
time_t rawtime;
|
||||
struct tm * timeinfo;
|
||||
char timestamp[21];
|
||||
char timestamp[22];
|
||||
size_t i;
|
||||
|
||||
if (label == NULL || buff == NULL)
|
||||
@ -3748,7 +3768,7 @@ mbus_hex_dump(const char *label, const char *buff, size_t len)
|
||||
time ( &rawtime );
|
||||
timeinfo = gmtime ( &rawtime );
|
||||
|
||||
strftime(timestamp,20,"%Y-%m-%d %H:%M:%S",timeinfo);
|
||||
strftime(timestamp,21,"%Y-%m-%d %H:%M:%SZ",timeinfo);
|
||||
fprintf(stderr, "[%s] %s (%03zu):", timestamp, label, len);
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
@ -3767,6 +3787,7 @@ mbus_data_error_print(int error)
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// XML RELATED FUNCTIONS
|
||||
@ -3886,7 +3907,7 @@ mbus_data_variable_record_xml(mbus_data_record *record, int record_cnt, int fram
|
||||
char str_encoded[768];
|
||||
size_t len = 0;
|
||||
struct tm * timeinfo;
|
||||
char timestamp[21];
|
||||
char timestamp[22];
|
||||
long tariff;
|
||||
|
||||
if (record)
|
||||
@ -3942,7 +3963,7 @@ mbus_data_variable_record_xml(mbus_data_record *record, int record_cnt, int fram
|
||||
if (record->timestamp > 0)
|
||||
{
|
||||
timeinfo = gmtime (&(record->timestamp));
|
||||
strftime(timestamp,20,"%Y-%m-%dT%H:%M:%S",timeinfo);
|
||||
strftime(timestamp,21,"%Y-%m-%dT%H:%M:%SZ",timeinfo);
|
||||
len += snprintf(&buff[len], sizeof(buff) - len,
|
||||
" <Timestamp>%s</Timestamp>\n", timestamp);
|
||||
}
|
||||
|
@ -191,7 +191,13 @@ mbus_serial_disconnect(mbus_handle *handle)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (handle->fd < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
close(handle->fd);
|
||||
handle->fd = -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -374,4 +380,3 @@ mbus_serial_recv_frame(mbus_handle *handle, mbus_frame *frame)
|
||||
|
||||
return MBUS_RECV_RESULT_OK;
|
||||
}
|
||||
|
||||
|
@ -127,7 +127,13 @@ mbus_tcp_disconnect(mbus_handle *handle)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (handle->fd < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
close(handle->fd);
|
||||
handle->fd = -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -262,4 +268,3 @@ mbus_tcp_set_timeout_set(double seconds)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user