La séptima vida

...o el gato así lo espera/teme

Rewrite of Device::Modbus

Have you ever heard that premature optimisation is the mother of all evil? Well, it is. But these are my reasons to rewrite Device::Modbus even before it was made public over CPAN:

  • The previous version included both clients and servers, and both TCP and RTU flavors. The rewrite cuts off the RTU and TCP parts of the protocol in different distributions.
  • I was reading 256 characters from the port (either serial or TCP port) but then detecting the end of messages became tricky. It seems that buffering in the serial port effectively erased the time between them, probably because I was using a USB-RS232 converter.
  • The code to parse incoming requests and responses was inside of the request and response modules. Clients only need to parse responses, and servers parse requests only; therefore, about half the code in those modules was not being used. Probably not a problem, though.
  • Profiling showed that more time was spent on Moo's internals than in my code, which suggests that my code is too simple to really need Moo.
I decided to move the parsing code to clients and servers, and to change the quantity of bytes read according to the data provided by the protocol. This should make it easier to find the frontiers between messages.

So, the new Device::Modbus is starting mainly as a re-write. Many of the tests were simply adapted, but the interface will change slightly.

The documentation of the modules as well as the articles in this blog must be updated, too.

As of today, I have a good deal of the core modules. Testing is still quite loose:

----------------------------------- ------ ------ ------ ------ ------ ------
File                                  stmt   bran   cond    sub   time  total
----------------------------------- ------ ------ ------ ------ ------ ------
blib/lib/Device/Modbus.pm            100.0  100.0    n/a  100.0    7.8  100.0
blib/lib/Device/Modbus/ADU.pm         82.9   87.5   11.1   75.0   15.5   71.9
blib/lib/Device/Modbus/Client.pm      84.6   75.0    n/a   90.5   11.7   85.3
blib/lib/Device/Modbus/Exception.pm   60.0    0.0    0.0   70.0    0.3   47.5
blib/lib/Device/Modbus/Request.pm     87.6   73.1   43.3  100.0   16.9   77.3
blib/lib/Device/Modbus/Response.pm    85.1   61.5   42.9  100.0    8.7   74.4
blib/lib/Device/Modbus/Server.pm      63.2   40.0   60.0   80.8    8.5   61.1
blib/lib/Device/Modbus/Unit.pm        96.0   56.2   33.3  100.0   11.8   84.7
.../lib/Device/Modbus/Unit/Route.pm  100.0   90.0   88.9  100.0   18.8   96.9
Total                                 81.2   60.0   41.9   89.1  100.0   75.4
----------------------------------- ------ ------ ------ ------ ------ ------

These are the milestones for the project:

  • Increase test coverage of the core modules to 90% on branches and conditions, and to 100% in statements and subroutines
  • Develop the RTU set of modules with appropriate test coverage
  • The RTU set of modules is able to talk with a real device
  • Test the RTU client and server on a Raspberry Pi
  • Add documentation to the core modules
  • Document the RTU modules
  • Develop the TCP set of modules, tests included
  • Use the TCP client to talk to a PLC
  • Get the TCP server working
  • Interface the server with an external database over a network
  • Document the TCP modules
  • Publish to CPAN

Most of the work will be simply to bring the old code and tests to the new frame, so it is not as much as it seems. Testing on the Raspberry Pi seems quite interesting, as well as the bit on the external database.

And yes, doing this will give me more reasons to write here.