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

Added modbus agent #638

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open

Added modbus agent #638

wants to merge 2 commits into from

Conversation

DaveBoettger
Copy link
Contributor

@DaveBoettger DaveBoettger commented Mar 11, 2024

Modbus agent should work with most Modbus devices simply by supplying the correct configuration file.
Specifically, this has been tested on the following devices on site: -VLT cooling loop pump controllers
-ELNet power monitors
-DSE 8610mkII generator controllers
Sample configuration files for each device are included.

Description

Motivation and Context

How Has This Been Tested?

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)

Checklist:

  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.

David Boettger and others added 2 commits March 11, 2024 17:45
Modbus agent should work with most Modbus devices simply by
supplying the correct configuration file.
Specifically, this has been tested on the following devices on site:
-VLT cooling loop pump controllers
-ELNet power monitors
-DSE 8610mkII generator controllers
Sample configuration files for each device are included.
Copy link
Member

@BrianJKoopman BrianJKoopman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR @DaveBoettger! A few comments and questions below. Biggest thing I'd say is the docs page. Some unit tests would be great, and I'm happy to help get that started, details in the comments.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we want to package these into the published package on PyPI. For lack of a better place to put them at the moment, can we move them to /examples/configs/modbus/ at the root of the repository?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for being so thorough with the docstrings! In order to easily view them can you create a docs page for this agent? It should live in docs/agents/modbus_agent.rst. There are many examples in that directory, and also documentation here for creating these pages.

To include the agent in the side bar, the new docs .rst page must be added to the docs/index.rst file, alphabetically, in the "Agent Reference" section.

"""

config_dir = os.environ.get('OCS_CONFIG_DIR')
path = os.path.join(config_dir, 'modbus_configs', dir_name)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would leave out 'modbus_configs', let the user decide what directory structure/naming they want. Otherwise this forces $OCS_CONFIG_DIR/modbus_configs/<user defined directory>.


def load_configs(dir_name, config_extension='yaml'):
"""
Loads all register configuration files form the specified directory (path).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"file form" -> "files from"



def twos(val, num_bytes):
"""Take an unsigned integer representation of a two's compilment integer and return the correctly signed integer
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please wrap lines to 80 characters. Lots of editors support automating this in some fashion, or have extensions to do so.

help="Starting action for the agent.")
pgroup.add_argument("--configdir", type=str, help="Path to directory containing .yaml config files.")
pgroup.add_argument("--sample-interval", type=float, default=10., help="Time between samples in seconds.")
pgroup.add_argument("--unit_id", type=float, default=1, help="Modbus unit id for module.")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Convention here is to use hyphens instead of underscores, please make this --unit-id, rather than --unit_id.

Comment on lines +456 to +468
{"fields":
{'Oil_pressure': {'value': 100.0, 'units': 'Kpa'},
'Coolant_temperature': {'value': 20.0, 'units': 'Degrees C'},
'Oil_temperature': {'value': 20.0, 'units': 'Degrees C'},
'Fuel_level': {'value': 100.0, 'units': '%'},
'Charge_alternator_voltage': {'value': 10.0, 'units': 'V'},
'Engine_Battery_voltage': {'value': 10.0, 'units': 'V'},
'Engine_speed': {'value': 4000, 'units': 'RPM'},
'Generator_frequency': {'value': 1.0, 'units': 'Hz'},
...
'connection': {'last_attempt': 1680812613.939653, 'connected': True}},
"address": 'localhost',
"timestamp":1601925677.6914878}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great to see! However I noticed that the documented fields here seem to differ from the register names in Generator_Engine_Data.yaml, i.e. 'Engine_oil_pressure' vs 'Oil_pressure'. Is this just a case of one of these two locations being out of date?

This documentation is primarily for the OCS control program writer who needs to reference these keys and might not have access to a running instance of the agent to reverse engineer which keys are available. So these sorts of differences matter here, but I realize it's tedious to keep multiple locations up to date.

There's also a sort of unique issue here in that this agent could be monitoring a different device with different registers, and thus different "fields". I'd like to capture that info here too.

My suggestion would be to include a general structure for the session.data, and describe how it's populated, while pointing to the example configuration files for the details of specific field names and possible value types, etc. Still include things that are always true in the general structure, like the timestamp. Sound good?

Comment on lines +233 to +244
if self.error_out_of_range:
try:
if val < rconfig['min_val']:
val = self.error_val
except KeyError:
pass

try:
if val > rconfig['max_val']:
val = self.error_val
except KeyError:
pass
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two questions here:

  1. How does self.error_val get set? It seems right now to always be None. This would run into issues on line 247 with the float() cast, but maybe I'm missing something.
  2. Would it make sense to distinguish between values below 'min_val' and values above 'max_val'?

try:
self.read_start = config['read_start']
except KeyError:
self.read_start = config['page'] * 256
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where does config['page'] come in? I don't see a 'page' key in any of the example YAML files, or any additions of the key elsewhere in the code.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would go above and beyond, but it would be useful to see some examples in the form of some unit tests for the code up to line 156, all the bit register code that doesn't involve actually communicating with a device. There are some docs for how to run the tests here.

The tests would live under socs/tests/agents/. There aren't a lot of examples in there, but you could check out the supersync tests.

Happy to talk more about this too.

@BrianJKoopman BrianJKoopman added the new agent New OCS agent needs to be created label Oct 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
new agent New OCS agent needs to be created
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants