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

Add support for modbus over serial (RTU) #41

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

matthijskooijman
Copy link

This PR:

  • takes the core commit of PR WIP attempt to get serial and RS485 Modbus-RTU working #35 by @iconnor (the commit that actually enables serial support, leaving out a bunch of seemingly unrelated commits), rebasing it on top of current master.
  • changes the parity setting to even (as modbus mandates and my device implements, but is not implemented on all devices it seems, so this should really be made configurable)
  • Adds a new commit to make the slave address configurable (also per register, so you can service multiple slaves on a single bus). I later noticed that WIP attempt to get serial and RS485 Modbus-RTU working #35 also implemented this, but I think my commit is preferred because it allows per-register configuration of the slave address. I've used the "slave" field for configuring this instead of "unit", since it seems that pymodbus is deprecating the "unit" parameter for this in favor of "slave" (though I believe this is not released yet, so we still pass "unit" to pymodbus).

I'm marking this as a draft pullrequest, since I do still have some doubts about the implementation:

  • This adds a number of extra configuration variables which are extracted from the config by modbus4mqtt.py and then passed to modbus_interface.__init__() separately. I'm not sure if this approach really scales well, maybe some other method of passing config as a dict or so should be considered.
  • The baudrate is now configurable, but the other serial settings (in particular parity) are now hardcoded. This should really be configurable, but see previous point.
  • There is some duplication of default values. modbus_interface.__init__() has default values for its parameters, but AFAICS these are never used, because mqtt_interface.connect_modbus() always passes values (and has its own defaults for values missing in the config file).
  • Selecting serial or tcp now happens through the variant, which seems a bit weird to me, but given the only other variant, sungrow is a variation on ModbusTcpClient, it makes sense like this, but does feel a bit weird. Maybe this requires a bit more thought.

For now, this code works well enough for my usecase, so I'll probably not put (much) more work in this (I could make some more updates if there is specific feedback), but I wanted to at least share this code in case it is helpful for others as-is already.

iconnor and others added 3 commits October 11, 2022 16:01
This allows a top-level "slave" entry in the config to set the slave
address globally (defaulting to 1 as before), but also allows overriding
the slave address for individual registers (which allows communicating
with multiple slaves on the same bus).
@@ -31,6 +31,7 @@ def __init__(self, hostname, port, username, password, config_file, mqtt_topic_p
self.prefix = mqtt_topic_prefix
self.address_offset = self.config.get('address_offset', 0)
self.registers = self.config['registers']
self.default_slave = self.config.get('slave', 1)
Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks for making these safer - I like it

if mask == 0xFFFF:
self._mb.write_register(addr, value, unit=0x01)
self._mb.write_register(addr, value, unit=slave)
Copy link
Contributor

Choose a reason for hiding this comment

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

Thank you for fixing up the hard-coded values

@tjhowse
Copy link
Owner

tjhowse commented Jan 24, 2023

@iconnor I've pushed up some commits to a fork of this branch to fix up the tests: master...3devo-serial-modbus

I haven't had time to 100% test and finish it off yet though. I also really don't like the "slave" terminology, and I think it's daft that upstream pymodbus is moving from "unit" to "slave".

@poucz
Copy link

poucz commented Oct 27, 2023

How does it look like with merge?
It would be useful for me.

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

Successfully merging this pull request may close these issues.

4 participants