Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature-reply-on-broadcast #75

Merged
merged 1 commit into from Jul 6, 2021
Merged

Conversation

dgoo2308
Copy link
Contributor

Reply on Broadcast

Purpose

Some ModBus libraries don't support Broadcast unitId=0 over tcp/ip what creates timeout and/or error condition in the tcp client.
While mbusd is already prepared not to wait for a reply on a Broadcast, mbusd does not send an answer to the client.

Change:

This merge request adds the option -b to mbusd startup options and replyonbroadcast as config file option to enable the reply on a Broadcast, defaulting to NO REPLY ON BROADCAST.
Updates the man mbus and mbusd -h or usage:

Usage: mbusd [-h] [-d] [-L logfile] [-v level] [-c cfgfile]
             [-p device] [-s speed] [-m mode]
             [-t] [-y sysfsfile] [-Y sysfsfile]
             [-A address] [-P port] [-C maxconn] [-N retries]
             [-R pause] [-W wait] [-T timeout] [-b]

Options:
  -h         : this help
  -d         : don't daemonize
  -L logfile : set log file name (default /var/log/mbus.log,
               '-' for logging to STDOUT only)
  -v level   : set log level (0-9, default 2, 0 - errors only)
  -c cfgfile : read configuration from cfgfile
  -p device  : set serial port device name (default /dev/ttyS0)
  -s speed   : set serial port speed (default 19200)
  -m mode    : set serial port mode (default 8N1)
  -A address : set TCP server address to bind (default 0.0.0.0)
  -P port    : set TCP server port number (default 502)
  -t         : enable RTS RS-485 data direction control using RTS
  -y         : enable RTS RS-485 data direction control using sysfs file, active transmit
  -Y         : enable RTS RS-485 data direction control using sysfs file, active receive
  -C maxconn : set maximum number of simultaneous TCP connections
               (1-128, default 32)
  -N retries : set maximum number of request retries
               (0-15, default 3, 0 - without retries)
  -R pause   : set pause between requests in milliseconds
               (1-10000, default 100)
  -W wait    : set response wait time in milliseconds
               (1-10000, default 500)
  -T timeout : set connection timeout value in seconds
               (0-1000, default 60, 0 - no timeout)
  -b         : reply on broadcast (default 0)

Test w pymodbus

    client = ModbusClient('localhost', port=1501)
    client.connect()
    rq = client.write_register(1, 10, unit=0)

Remark: Without the pymodbus.client broadcast_enable=True, to simulate libraries that don't have the broadcast_enable on a tcp modbus connection.

original or new without -b

2021-06-19 13:06:17,583 MainThread      DEBUG    sync           :215      Connection to Modbus server established. Socket ('127.0.0.1', 52444)
2021-06-19 13:06:17,583 MainThread      DEBUG    transaction    :139      Current transaction state - IDLE
2021-06-19 13:06:17,583 MainThread      DEBUG    transaction    :144      Running transaction 1
2021-06-19 13:06:17,583 MainThread      DEBUG    transaction    :272      SEND: 0x0 0x1 0x0 0x0 0x0 0x6 0x0 0x6 0x0 0x1 0x0 0xa
2021-06-19 13:06:17,583 MainThread      DEBUG    sync           :76       New Transaction state 'SENDING'
2021-06-19 13:06:17,583 MainThread      DEBUG    transaction    :286      Changing transaction state from 'SENDING' to 'WAITING FOR REPLY'
2021-06-19 13:06:20,587 MainThread      DEBUG    transaction    :302      Transaction failed. (Modbus Error: [Invalid Message] No response received, expected at least 8 bytes (0 received))
2021-06-19 13:06:20,587 MainThread      DEBUG    socket_framer  :147      Processing:
2021-06-19 13:06:20,587 MainThread      DEBUG    transaction    :464      Getting transaction 1
2021-06-19 13:06:20,587 MainThread      DEBUG    transaction    :224      Changing transaction state from 'PROCESSING REPLY' to 'TRANSACTION_COMPLETE'
Traceback (most recent call last):
  File "/Users/dgoo2308/git/modbus_test/c.py", line 101, in <module>
    run_sync_client()
  File "/Users/dgoo2308/git/modbus_test/c.py", line 60, in run_sync_client
    assert(not rq.isError())     # test that we are not an error
AssertionError

mbusd -b

2021-06-19 13:01:55,616 MainThread      DEBUG    sync           :215      Connection to Modbus server established. Socket ('127.0.0.1', 52156)
2021-06-19 13:01:55,616 MainThread      DEBUG    transaction    :139      Current transaction state - IDLE
2021-06-19 13:01:55,616 MainThread      DEBUG    transaction    :144      Running transaction 1
2021-06-19 13:01:55,616 MainThread      DEBUG    transaction    :272      SEND: 0x0 0x1 0x0 0x0 0x0 0x6 0x0 0x6 0x0 0x1 0x0 0xa
2021-06-19 13:01:55,616 MainThread      DEBUG    sync           :76       New Transaction state 'SENDING'
2021-06-19 13:01:55,616 MainThread      DEBUG    transaction    :286      Changing transaction state from 'SENDING' to 'WAITING FOR REPLY'
2021-06-19 13:01:55,618 MainThread      DEBUG    transaction    :374      Changing transaction state from 'WAITING FOR REPLY' to 'PROCESSING REPLY'
2021-06-19 13:01:55,618 MainThread      DEBUG    transaction    :296      RECV: 0x0 0x1 0x0 0x0 0x0 0x6 0x0 0x6 0x0 0x1 0x0 0xa
2021-06-19 13:01:55,618 MainThread      DEBUG    socket_framer  :147      Processing: 0x0 0x1 0x0 0x0 0x0 0x6 0x0 0x6 0x0 0x1 0x0 0xa
2021-06-19 13:01:55,618 MainThread      DEBUG    factory        :266      Factory Response[WriteSingleRegisterResponse: 6]
2021-06-19 13:01:55,618 MainThread      DEBUG    transaction    :453      Adding transaction 1
2021-06-19 13:01:55,618 MainThread      DEBUG    transaction    :464      Getting transaction 1
2021-06-19 13:01:55,618 MainThread      DEBUG    transaction    :224      Changing transaction state from 'PROCESSING REPLY' to 'TRANSACTION_COMPLETE'
2021-06-19 13:01:55,618 MainThread      DEBUG    transaction    :139      Current transaction state - TRANSACTION_COMPLETE

test libmodbus

ModBus version: 3.1.6

#include <modbus/modbus.h>
int main(int argc, const char * argv[]){
   modbus_t * ctx=modbus_new_tcp_pi("mbus-5", "502");
   modbus_set_slave(ctx,0);
   modbus_set_debug(ctx, TRUE);
   modbus_write_bits(ctx, 229, 1, &data);
   modbus_close(ctx);
   modbus_free(ctx);
  return 0;
}

original or new without -b

[00][01][00][00][00][08][00][0F][00][E5][00][01][01][01]
Waiting for a confirmation...
ERROR Connection timed out: select

mbusd -b

[00][01][00][00][00][08][00][0F][00][E5][00][01][01][01]
Waiting for a confirmation...
<00><01><00><00><00><08><00><0F><00><E5><00><01>
OK

@3cky
Copy link
Owner

3cky commented Jun 21, 2021

Thanks for the PR! Overall I like the idea, but still not sure that a simple request echo will work as expected in all situations. No doubt it will be correct for force single coil/register functions, but force multiple coil/register functions responses are different from simple request echo, not saying read functions. Do you have some examples of Modbus TCP client software that is expecting such responses for broadcast requests?

@dgoo2308
Copy link
Contributor Author

@3cky

are the ones I run into and I'm aware of.

I get your point, I'll setup some testing with other writes beside force single coil/register functions and study the responses, I didnt think about that, but yes it falls under 'a write' and thus can have a broadcast.

Thanks

3cky added a commit that referenced this pull request Jul 6, 2021
@3cky 3cky merged commit 6a95a73 into 3cky:master Jul 6, 2021
@3cky
Copy link
Owner

3cky commented Jul 6, 2021

Hello @dgoo2308,

I merged your PR with some small fixes. Please note I decided to change the semantics of replyonbroadcast config file option. Now it should have a value y or yes to enable reply on a broadcast.

Thank you again!

@dgoo2308
Copy link
Contributor Author

@3cky thanks, looking good.

@dgoo2308 dgoo2308 deleted the reply-on-broadcast branch July 17, 2021 08:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants