-
Notifications
You must be signed in to change notification settings - Fork 39
Implement Modbus UDP #85
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
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the contributin @StefanNienhuis ! 😊
I am not deep into the UDP protocol itself and also not into the implementation here in the repo.
As we have no internal use of Modbus RTU via UDP, I also don't see an issue against adding it to the repo here.
I've added a few comments, nothing critical here
|
@tretmar Thanks for the review. I've made the changes. |
dammarco
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm 👍
|
What's missing to get this merged? |
|
@StefanNienhuis after looking through the code (and not being a network protocol guy) I have a situation here in https://github.com/evcc-io/evcc/blob/master/meter/goodwe/server.go where we're sending UDP requests to a fixed port and the device replies on a fixed port: // receiver
addr, err := net.ResolveUDPAddr("udp", "0.0.0.0:8899")
if err != nil {
return nil, err
}
instance.conn, err = net.ListenUDP("udp", addr)
if err != nil {
return nil, err
}
// sender
addr, err := net.ResolveUDPAddr("udp", net.JoinHostPort(ip, "8899"))
if err == nil {
// hand-built RTU
_, err = m.conn.WriteToUDP([]byte{0xF7, 0x03, 0x89, 0x1C, 0x00, 0x7D, 0x7A, 0xE7}, addr)
}
// listener
buf := make([]byte, 1024)
n, addr, err := m.conn.ReadFromUDP(buf)
if err != nil {
continue
}Do you see any chance to support such a scenario? Or maybe I misunderstand this PR or UDP in general? |
|
@andig I’m not quite sure what your goal is, but I see it’s intended for Goodwe inverters, which is exactly what I built this for. The only thing that would be missing is supporting the AA55 prefix it sends before responses on some models, but that may not be required for your model. |
|
I think I'm confused by the fact that your code does not have a UDP listener, but I guess I'm just over-complicating UDP mentally. |
|
Go abstracts away large parts of the UDP protocol details in their network implementation. This allows you to have a UDP ‘connection’ that can send and receive data similar to TCP, even though there isn’t a persistent connection. |
|
Sorry, it is common for us that the authors themselves are merging the PR but I guess you either are not allowed or just not think about merging your own PRs 🤔 As this has no impact for us, I will merge it now :) |
|
@StefanNienhuis confirmed working in evcc-io/evcc#12752 (reply in thread). Unfortunately we're now confronted with #85 (comment). Seems forking would be the right way to go to implement a workaround for this device defect. |
|
Yeah, although it's pretty trivial to implement, it may be out of scope for this project to implement such device specific behavior. Not sure who decides what goes in this project and what not, but since you merged this PR, what do you think @tretmar? In case you're not familiar, some families of Goodwe inverters accept their commands in normal Modbus format, but send their response in Modbus format with the bytes AA55 prefixed. |
|
I'd say that device specific behavior doesn't belong into this project here 🤔 Forking brings the risk of getting out of sync really quickly. Another idea is to create an option that you can configure that can deal with the response prefix of AA55. And only use it for your project then. |
@tretmar nobody contributing here has that permission. See #45 (comment), three years old. There's still a queue of PRs that need attention like the important #81.
Not responding brings the risk of forking.
How would I do that without a fork or a merged PR? |
Well, either forking or merged PR ofc. Sure, if you face the issue that you have to wait multiple months to get it merged, I understand your concerns. |
@dammarco - May I ask how have you became a contributor with rights to merge in this project ? |
|
@StefanNienhuis thank you for adding ModbusUDP. I've noticed that the current implementation does not use any timeouts. This can lead to indefinite wait times, at least in my tests. It would be great, if similar |
This PR implements Modbus RTU over UDP.
Also implements handling of UDP addresses in Modbus CLI and documents this usage in the README.
This solves #50.