-
Notifications
You must be signed in to change notification settings - Fork 949
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
Fix writing to serial (rs485) on windows os. #2191
Merged
Merged
Changes from 1 commit
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
The if/elif is not very logical it seems you could simplify it a lot.
Secondly I am still not convinced this is the right way, at least please explain why CI that also runs on windows works.
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.
The if/elif is checking for the platform type. This could also be done with the platform library to be a bit more specific and check if it is Windows. Agreed could be simplified.
There also may be a more cross-platform way. I didn't spend much time on it as I just wanted to get it working for a few tests. This could be closed and just submitted as an issue for further investigation.
I'm not exactly sure why the CI is passing for windows but not working on real hardware. I would assume it is because the CI doesn't test real hardware but a NULLMODEM_HOST which may be behaving differently than hardware device. I did run the same test code (except port name) on Linux with no issues.
Here is the Exception that I get when running on Windows, Python 3.12.0:
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.
The high level tests uses null modem, which basically bypasses pyserial, but there are low level tests that uses pyserial (transport itself), however they do NOT use the serial interface but the socket interface, and that might be the difference.
Apologies if I come across as a bit negative, but the problem is that I have to maintain the code long term so while I look positive at (nearly) any PR, I give a feedback that ensures it is not making maintenance harder.
Precise comments:
if / elif, as you admitted it can be simplified, this is important because in a year from now I (or someone else) will start thinking what is the reason that it is complex, what have I overlooked...
Cross platform: this PR should not be closed, it solves a problem, we just need to get it right. A simplification would be to only use the create_task you suggest, and remove the add_writer totally....I am all in a favor of that.
So to sum up:
I look forward to review a new version from you...I hope you can see that I am positive and your PR have value !
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.
I looked into this a bit more. It appears if it is windows it should set the poll_task which in the intern_write_ready does not use the fileno() to write.
In setup it is specifically setting the poll_task on windows.
It looks like what was happening was the write function was being called before the setup function is ran.
I put a break point in the write function at the add_writer line and noticed that it was being hit. Which according to the setup function it shouldn't be since it is Windows. I then added a break point to the setup function and noticed that the write function is called once before the setup function is ran.
Adding a timeout after the connect and before a read_input_registers (or other modbus operation) allowed the setup function to finish before the write operation. I then did not receive any exceptions.
Looking at the create_serial_connection you can see that the transport.setup is scheduled to run once the event loop becomes idle. This means that read and write operations can happen before the setup function is run.
Calling the setup function to run immediately mitigates this issue.
I think my original changes should be rejected and this change be implemented instead or the connected function
(that is typically awaited after client creation) wait for the connection_made handler to finish, which is called from the setup function.
Thoughts?
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.
Sounds correct, please update the PR