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

change Find method #85

Open
blueskit opened this issue Jan 9, 2023 · 1 comment
Open

change Find method #85

blueskit opened this issue Jan 9, 2023 · 1 comment

Comments

@blueskit
Copy link

blueskit commented Jan 9, 2023

Currently, there is a use case as follows: As a ModbusServer, the client (ModbusRTU) of the other party requires a non-zero unitIdentifier, which prevents access to the data in the ModbusServer.

+-------------------+            +---------------+           +------------------+ 
|                   |     TCP    |               |   RS485   |                  |
| ModbusTcpServer   |   <----->  | ModbusGate    |  <------> | ModbusRTU Client |
| (FluentModbus)   |            | (Hardware)    |           |                  |
+-------------------+            +---------------+           +------------------+

After inspection, the Find() method in class ModbusServer is as follows:

        private Span<byte> Find(byte unitIdentifier, Dictionary<byte, byte[]> map)
        {
            if (unitIdentifier == 0)
            {
                if (map.Count == 1)
                    return map.First().Value;

                else
                    throw new ArgumentException(ErrorMessage.ModbusServer_ZeroUnitOverloadOnlyApplicableInSingleUnitMode);
            }

            else
            {
                if (!map.TryGetValue(unitIdentifier, out var buffer))
                    throw new KeyNotFoundException(ErrorMessage.ModbusServer_UnitIdentifierNotFound);

                return buffer;
            }
        }

If the Find method is changed to a protected virtual method, then the problem can be solved by deriving a class from ModbusServer as follows.

 public class ModbusSlaveOneTcpServer : FluentModbus.ModbusTcpServer
 {
	  ModbusSlaveOneTcpServer()
	  {
		AddUnit(1);
	  }
          
        proteted override Span<byte> Find(byte unitIdentifier, Dictionary<byte, byte[]> map)
        {
           if (map.Count == 1 || unitIdentifier==0)
               return map.First().Value;
          else if (map!=null && map.TryGetValue(unitIdentifier, out var buffer))
                return buffer;
          else
               throw new KeyNotFoundException(ErrorMessage.ModbusServer_UnitIdentifierNotFound);
        }
    }

Please change the Find method in class ModbusServer to a protected method,
or if there is a better way, please consider it.

@Apollo3zehn
Copy link
Owner

Hi, thanks for your suggestion. I am wondering why you cannot simply call AddUnit(1) in your derived class (as you did in ModbusSlaveOneTcpServer) and then always work with that unit?

You can access the corresponding registers by calling e.g. GetHoldingRegisters(unitIdentifier: 1) or GetHoldingRegisterBuffer<T>(unitIdentifier: 1), etc.

Or did I overlook something?

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

2 participants