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

Fix register type check for size bigger than 3 registers (6 bytes) #1323

Merged
merged 4 commits into from
Feb 6, 2023

Conversation

duc996
Copy link
Contributor

@duc996 duc996 commented Jan 31, 2023

This commit fixes the register type check for configuration where more than 3 registers are configured as one area (I think for the moment this happens only for string types for the moment).
I updated unit tests for this case.

@janiversen
Copy link
Collaborator

Did you try the test ?

please remember what I wrote make a test case thst shows the problem, add your fix and check that the test works.

your test does not work with your fix.

@duc996
Copy link
Contributor Author

duc996 commented Jan 31, 2023

Did you try the test ?

please remember what I wrote make a test case thst shows the problem, add your fix and check that the test works.

your test does not work with your fix.

Yes, I run the test, but only the simulator test but other tests are broken.
I missed the point that the commit order is important. I have updated the pull request with 1. the updated test case and 2. the correction.

A little side note: who should I start my tests? I used the commend from the CI, but there is also the pylint. Is there any command to start all tests from CI? Also serial-ModbusRtuFramer and serial-ModbusAsciiFramer are failing most of the time on my local PC event without my patch so I think this is not related to it.

@janiversen
Copy link
Collaborator

Read the documentation that is a good start.

@duc996
Copy link
Contributor Author

duc996 commented Jan 31, 2023

Read the documentation that is a good start.
Thanks, I found the check_ci.sh script.

@janiversen
Copy link
Collaborator

Let me take your questions one by one.
a) commit order is not important ! CI checks the Pull Request as a merged commit.
b) of course other tests break, it is one library, so changes in one corner can easily affect another part.
c) I have not idea, what you mean by serial-ModbusRtuFramer and serial-ModbusAsciiFramer fails, the test cases must work also on your PC. If it is your usage, well...

I will take a look first at your test case, then at the production code.

Copy link
Collaborator

@janiversen janiversen left a comment

Choose a reason for hiding this comment

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

Nice catch in the tests !!! Seems I forgot to test that one.

Actually I think you are the first to try strong typing.

return False
if self.registers[i].type in check:
continue
if self.registers[i].type is CellType.NEXT:
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is not right: real_address + 0 may not be NEXT, because it means you read off base.

For BITS, UINT16 next is never allowed (they occupy exact 1 register).
For UINT32, FLOAT32, first address must never be NEXT, second address must be NEXT, 3 address never etc....
For STRING first address must be STRING, next addresses must be NEXT / STRING.

So it is a bit more complex.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As I said before, I don't really understand the NEXT celltype.
Why should it not be authorized to read the UINT32 in two requests or to read two UINT32 values in one request, but it's authorized to read only one register of the UINT32.
For strings it's similar, if there is a longer string and I would like to get only a part of it, why this wouldn't be allowed?
Initially I thought the type check is more of a function code check.

Copy link
Collaborator

Choose a reason for hiding this comment

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

NEXT is quite easy, it is the second register in UINT32, FLOAT32, and remaining registers in STRING.

Consider this sequence of registers:
12: UINT32, 13: NEXT, 14: UINT32, 15: NEXT, 16:UINT32, 17:NEXT

The following are valid reads:
Read_holding(12, 2)
Read_holding(12, 6)
Read_holding(14,2)

The following are invalid (Because they do not read whole UINT32)
Read_holding(12, 1)
Read_holding(13, 1)
Read_holding(12, 3)

FLOAT32 are exactly the same.

STRINGS are not so different:
12: STRING, 13: NEXT, 14: NEXT, 15: NEXT, 16: STRING, 17: NEXT

The following are valid:
read_holding(12, 4)
read_holding(12, 6) # read 2 complete strings (allowed just as it is allowed to read multiple UINT32)
read_holding(16, 2)

Type check is there to ensure you read the strings correctly, so the following is not allowed:
read_holding(12, 1)
read_holding(12, 1)
read_holding(13, 1)

Does that help ?

Copy link
Collaborator

Choose a reason for hiding this comment

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

The type check is there to ensure you read the registers as the designer of the device intended. It is a "verification", and you can find X reasons why it should be different, but then the answer is configure it to False!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes, much better :)

@janiversen
Copy link
Collaborator

When changing validate_type, we should also check that count for UINT32, FLOAT32 is a multiple of 2.

@duc996
Copy link
Contributor Author

duc996 commented Jan 31, 2023

Thanks for your reposes.
for a): I thought it's for you to see the testcase first and can judge if it's a valid usecase.
b) I was to optimistic :)
and c) if I run the check_ci script twice, I get e.g. the following error:

OSError: [Errno 98] error while attempting to bind on address ('127.0.0.1', 5030): address already in use --------------------------------------------------------------- Captured log call --------------------------------------------------------------- INFO root:client_async.py:44 ### Create client object INFO root:client_async.py:120 ### Client starting DEBUG pymodbus.client.serial:serial.py:107 Starting serial connection WARNING pymodbus.client.serial:serial.py:125 Failed to connect: Could not open port socket://127.0.0.1:5030: [Errno 111] Connection refused ------------------------------------------------------------- Captured log teardown ------------------------------------------------------------- DEBUG asyncio:selector_events.py:54 Using selector: EpollSelector ============================================================ short test summary info ============================================================ FAILED test/test_examples.py::test_exp_async_server_client[serial-ModbusRtuFramer-5020-10] - AssertionError =================================================== 1 failed, 459 passed, 1 skipped in 6.98s ==================================================== "pytest --numprocesses auto" command filed with exit code 1.

@janiversen
Copy link
Collaborator

that is because you have something running that blocks port 5030.

@duc996
Copy link
Contributor Author

duc996 commented Jan 31, 2023

that is because you have something running that blocks port 5030.
No, I don't have anything running on port 5030. The first start is running ok, but the following tests don't work. I had to run my tests several times :)
It's on my linux pc and with netstat I can see that the sockets are in TIME_WAIT. I have to wait for this state to finish and than the test is reworking. It seems on my system this timeout is 60 seconds.

@janiversen
Copy link
Collaborator

Look at CI, we use Linux and it works.

@janiversen janiversen merged commit cc4c06b into pymodbus-dev:dev Feb 6, 2023
@janiversen
Copy link
Collaborator

Thanks.

alexrudd2 pushed a commit to alexrudd2/pymodbus that referenced this pull request Feb 21, 2023
…ymodbus-dev#1323)

Expand unit test to check for strings larger than 6 bytes (3 modbus registers)
Co-authored-by: Georg Hofmann <georg@hofmannsweb.com>
Co-authored-by: jan Iversen <jancasacondor@gmail.com>
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 21, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants