Modbus TCP Agent

Hi everyone,

I’m configuring the Modbus TCP agent in OpenRemote, but I can’t find an attribute for specifying the register address (Holding Register, Coil, etc.). Is there a way to define this in the configuration?

Also, what’s the best way to test if the agent is correctly reading/writing values?
Any help would be greatly appreciated. Thanks in advance!

Hi @miryam ,

I am assuming that you have checked out and are testing my Modbus agent branch.

The individual read/write settings can be configured using the agent link. You can press on “add parameter” in the agent link configuration item, and there, there will be 4 more configuration parameters in the agent link that you can specify. On one of those, you will be able to set the type of register you are reading from.

I would like to let you know that, as with any OpenRemote branch, the changes on it are not currently set in stone, and can change. This means that there is a possibility the structure of the agent, agent link, protocol, etc. could change, leading to issues with the connection, etc. If you would like to avoid that, then I suggest you wait for the PR to be merged.

Best of luck!

1 Like

Hi @panos,

I am new here and try to find out more about the exciting openremote project. One importante use case I see in our company is integrating devices with modbus TCP interface. So I tryed out your Modbus TCP Agent and had trouble defining the ModbusDataType. In your source code I found this parameter, but not in the manager UI - what could be the reason for that?

Thanks!

Good afternoon @sebax ,

The documentation for the Modbus agent is currently ongoing, but I believe I can help:

The ModbusDataType is the enum used in the agent link for the Read Value Type and Write Value Type parameters.

Basically, those two agent link parameters, are used for parsing the resulting data from/to the Modbus server. They come from PLC4X’s documentation, and the value selected is then put in the query string sent to the Modbus server. PLC4X takes it from there and appropriately parses the response from the server (vice versa for sending the value to the Modbus server).

So if I select UINT in the Read Value Type, PLC4X will parse the response to UINT from the Modbus server before handing it back to OpenRemote.

Here’s the PLC4X documentation for the Modbus data types:

https://plc4x.apache.org/plc4x/latest/users/protocols/modbus.html#_data_types

You can find how it’s used in AbstractModbusProtocol:135 for scheduling the read request to the Modbus server.

Hi @panos ,

thanks for you quick response and the explanations! I still have problems reading date from the Modbus server.

The following image shows the results of one of my tests:

A modbus tester shows the server is communicating with the chosen parameters. If I use the same parameters in OpenRemote it won’t work.

As you can see in the image no valid data is returned. Is there probably an issue with the address? The server (PV-inverter from SMA) uses the shorter format (3XXXX)? Does the agent pass the given “Read Adress” directly to the server, or does it expect the longer version? I don’t now. Probably you have an idea…

Thanks for your help!

Good morning @sebax ,

Looking at your screenshot, I can tell that the address you should use there is probably 776, assuming that you’re not trying to read input register 30776, but rather trying to read input register 776. Our implementation simply uses the offset of the register, not the complete address (so not register 40002 meaning that we’re reading holding register 2).

Our implementation simply uses the read memory area configuration input from the agent link to do this transformation (i.e. start reading from the submitted memory area); so if you want to read register 776 from the input register memory area, you can just use INPUT as read memory area and 776 for read address.

Using your input from your screenshot, the request sent to the server would be formatted something like: input-register:30775:DINT, meaning that it’s going to go to the input registers, and request address 30775.

I believe you’re looking for something like input-register:776:DINT (make sure to check if you actually want DINT, meaning double integer).

EDIT: you may need to also try out address 775, in case it’s referring to an offset and not an address.

Let me know if this helps!

Hello @panos,

unfortunately it is not working yet, even considering your remarks. And yes it is double integer I need. That is also the reason why it needs to read two registers in one request (775 AND 776). But I guess this is automatically done by the code if I choose the Read Value Type = DINT, right? Then the request to the server should be according PLC4X documentation like {memory-Area}{start-address}:{data-type}[{array-size}]input-register:30775:DINT[2].

Is there any way to print the polling request sent to the server, e.g. in some logfile?

Kind regards!

Good afternoon @sebax ,

Theoretically that’s how it should work, I’m quite sure that I tested that. I will have to reproduce it on my PC and let you know.

In the meantime, this should mean that you started getting (some sort of) data from register 775 or 776, right?

Thanks!

Good morning @panos,

unfortunately I don’t get back useful kind of data. If I define the data type “INT” or “DINT” I only get “-1” and if I try “UINT” or “UDINT” I get “65535” / “4294967295” which is binary “1111111111111111” / “11111111111111111111111111111111” - independent which register I choose (775 or 776).

Is it possible that I have some firewall problem? But than the status of the agent wouldn’t be “CONNECTED”, right?

Thank you!

Hi @panos,

do you have any new ideas for solving my problem?

Thanks a lot!

Hey @sebax ,

We just released a new OpenRemote version, 1.6.1, that contains this PR. I believe it would solve your issue. It basically allows the Modbus agent to read the appropriate amount of registers depending on the datatype selected (that can be manually overriden if needed using Read register length). So if you use DINT, the modbus agent will read the register you input plus the next one to parse the correct number.

So make sure to update to the latest version of OpenRemote, and select DINT for the register data type.

Please let me know if this fixes the issue!

Hallo @panos,

the changes in the new release seem very sensible. But for my setup it is not the solution - I still have the same problem. I am running out of ideas…

Hi @sebax ,

So you tried to read a DINT from input register 776 and that returns 65535?

Are you sure that the data type that needs to be parsed is a DINT?

That seems a bit weird, can you make sure that you can read the correct value using other software? I’d recommend the Java app ModbusMechanic. If you can retrieve the value correctly from ModbusMechanic, send me a screenshot and I’ll try to figure out what’s wrong.

It’s also fine if you can send over the Modbus request/response from a successful request, if your software can do that.

Theoretically, a DINT will read registers 775 and 776, are you sure those are the registers you should be using?

I’d appreciate a screenshot of your agent link. Thanks!

Hi @panos ,

I finaly found time for testing with ModbusMechanic as you suggested. I got the following result:

Today I also tested again with openRemote and got an correct result with the following configuration: Read Value Type: INT, Read Address: 30776. With DINT / INT and 30775 it was not working. The last testing shows two open issues for me:

  1. Last week I tested with same parameters and got no result → in the meantime I restarted the system → Problem: there is no feedback if some process is frozen.
  2. According modbus-register definition of the inverter it should be signed 32 bit, so it should work with “DINT”.

Happy to hear that it worked! It seems that the two types of referring to a modbus address (30776 vs. input register 776) was mixed up. Thanks for letting me know it worked!