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

Modify functionality of any single unit special case #97

Open
ChrisProto opened this issue Sep 7, 2023 · 0 comments
Open

Modify functionality of any single unit special case #97

ChrisProto opened this issue Sep 7, 2023 · 0 comments

Comments

@ChrisProto
Copy link

ChrisProto commented Sep 7, 2023

This is related to Issue #93 "Modify functionality of single unit zero special case". In that issue, I described special functionality that we can have with just a single unit defined with a unit identifier of zero.

Since that time, I realized that this special functionality is not dependent upon a unit identifier of zero, and that we can actually allow this with any single unit.

In our case, I wanted to create a single TCP unit with Identifier 1, and have it accept any incoming Unit Identifier. (The Unit Identifier in the response is the same as what was supplied in the response. This was fixed earlier in changes related to Issue #93.)

I have created a pull request into your dev branch with these changes.

Future Ideas
FluentModbus is different from the previous package we were using because it supports multiple units in the Server classes. This will allow us to create a Modbus router. (You have probably already thought of this, but here are some of my observations.)

For example, we could create a Server that contains ten units, with Identifiers 1 through 10.

  • Imagine that Units 1 through 5 are just internal units. There is some external data acquisition mechanism that is retrieving values from some non-Modbus equipment, and then updating register and coil values in these internal Modbus Units to make them available to Modbus clients.
  • Imagine that Units 6 through 10 are external units that are actually Modbus RTU devices. We would receive incoming TCP requests and make a corresponding RTU request to the device. When that device responds, we make a corresponding response to the original client.
  • Finally, let's say that we create a Unit 0 that describes the router status. It could contain registers indicating how many units are connected, how many requests have been processed, how many errors have happened, etc.

In this case, we don't have a single unit, so the special handling would not apply. Specifically:

  • We cannot ignore incoming Unit Identifiers; they must be specified so we can choose the correct unit.
  • Handling broadcast messages (Unit Identifier zero) can become tricky because we have an internal router status unit 0. (This is probably a good reason not to use zero as the router status unit. Perhaps its Unit Identifier should be 255 (0xFF).)

Suppose that some of the ten units we have defined can accept broadcast messages and some cannot (or the engineer setting this up wants to prohibit broadcast messages to those units.) We need to keep this kind of configuration information on a per-Unit basis.

I put some comments in the code to this effect: I think that we should create a UnitInfo class that defines each Unit. It would contain the Unit Identifier, the four buffers for data, routing information, and other configuration parameters. It would give us the following benefits:

  1. Gather all the unit parameters into one place.
  2. Allow us to use a lock to control access to the list of units. This would allow us to add or remove units dynamically while the server is running.
  3. Allow for more efficient processing. Once we locate the UnitInfo object for the unit that can handle an incoming message, then we can pass that reference to as many methods as needed to process the message.

The UnitInfo class would contain properties like these: (This is not actual code.)

unsigned byte UnitIdentifier

byte[] InputRegisters
byte[] HoldingRegisters
byte[] InputCoils
byte[] HoldingCoils

boolean UnitAcceptsBroadcast
boolean UnitIgnoresUnitIdentifiers (This only makes sense for a single unit, and would be ignored otherwise.)

ModbusClient ModbusClient  (This is the external unit we will forward messages to.)

To handle broadcast messages, we would need to select a list of these UnitInfo objects where UnitAcceptsBroadcast is true and then process the incoming message for each one. Note that typically broadcast messages get no response, so they are used for writing the same value to multiple units.

Let me know what you think.

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

No branches or pull requests

1 participant