gijzelaerr / python-snap7

A Python wrapper for the snap7 PLC communication library
http://python-snap7.readthedocs.org/
MIT License
643 stars 246 forks source link

check_as_completion eats firsts bytes while reading DB #423

Closed luewh closed 1 year ago

luewh commented 1 year ago

Hello.

I'm working in a pipenv with:

Python 3.10.1
click==8.1.3 - colorama [required: Any, installed: 0.4.6]
python-snap7==1.3

PLC : S1516-3

Here is the code that occurs issues :

...
db_number = 4
start = 0
size = 14
buffer = ctypes.c_buffer(size,size)
as_read = client.as_db_read(db_number, start, size, buffer)

i = 0
while(client.check_as_completion(buffer)):
    i += 1
...
for i in bytearray(buffer):
    print(i)

What I get always begins with 4 bytes of 0, this is the result that I suppose to get : image

So I change a little bit the code :

...
db_number = 4
start = 0
size = 14
buffer = ctypes.c_buffer(size,size)
as_read = client.as_db_read(db_number, start, size, buffer)

for i in range(15):
    print(client.check_as_completion(buffer))
time.sleep(1)

data = client.db_read(db_number, start, size)
for i, i2 in zip(bytearray(data),bytearray(buffer)):
    print(i,"---",i2)

What happen is when check_as_completion() become once or more 0 (reading finished) 4 firsts bytes become 0, otherwise it works perfect (I have to add a sleep in this case otherwise it says RuntimeError: b'CLI : Job pending') image image image

swamper123 commented 1 year ago

Have you checked out the test method for that? https://github.com/gijzelaerr/python-snap7/blob/b278707d750522f0f465dd4ac101703a186f284d/test/test_client.py#L606

It's made a bit differently by using as_area_read(), but you still need the "check_status" part, instead of buffer.

luewh commented 1 year ago

Never mind, I'm a idiot. I give the buffer that I use to store data to check_as_completion, hence my result get overwritten. So I give it another buffer then I print the buffer2 and its return value :

...
db_number = 4
start = 0
size = 14
buffer = ctypes.c_buffer(size,size)
buffer2 = ctypes.c_buffer(2,2)
as_read = client.as_db_read(db_number, start, size, buffer)

for i in range(15):
    print(client.check_as_completion(buffer2))
    print(bytearray(buffer2))
time.sleep(1)

data = client.db_read(db_number, start, size)
for i, i2 in zip(bytearray(data),bytearray(buffer)):
    print(i,"---",i2)

image Now I got the correct result, but since the buffer2 doesn't change what it is used for ? Am I using it in a wrong way ?

(I'm just a beginner, I haven't understood a single thing from your test_check_as_completion @swamper123 ...)