Giter VIP home page Giter VIP logo

python-snap7's Introduction

About

This is a ctypes based python wrapper for snap7. Snap7 is an open source, 32/64 bit, multi-platform Ethernet communication suite for interfacing natively with Siemens S7 PLCs.

Python-snap7 is tested with Python 3.7+, on Windows, Linux and OS X.

The full documentation is available on Read The Docs.

Installation

If you are running Windows 10, Mac OS X or GNU/Linux on an Intel x64 compatible platform you can use the binary wheel installation:

$ pip install python-snap7

Ofterwise, please read the online installation documentation.

Credits

  • Gijs Molenaar (gijs at pythonic dot nl)
  • Stephan Preeker (stephan at preeker dot net)

Both authors are available for contracting to improve python-snap7. Please contact us at the email address above for inquiries.

Special thanks to

  • Davide Nardella for creating snap7
  • Thomas Hergenhahn for his libnodave.
  • Thomas W for his S7comm wireshark plugin
  • Fabian Beitler and Nikteliy for their contributions towards the 1.0 release
  • Lautaro Nahuel Dapino for his contributions.

python-snap7's People

Contributors

1ultimat3 avatar cadawg avatar crusher83x avatar cube707 avatar ellepdesk avatar ericonetto avatar gijzelaerr avatar imba-tjd avatar kristbaum avatar lamelynx avatar lautarodapin avatar lkraider avatar loicgrenon avatar lubbbert avatar nikteliy avatar ofloo avatar openarchitect avatar pauluap avatar petertm avatar schlamar avatar spreeker avatar swamper123 avatar tathar avatar tmcolby avatar v-zhuravlev avatar victorclaessen avatar vmsh0 avatar xybsoft avatar yingliangzhe avatar zsisamci avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

python-snap7's Issues

I Can't run the example.py

It shows a valueError: Procedure called with not enogh arguments (16 bytes missing) or wrong calling convention.

It raised by client.connect(PLC_ip, 0,0)

test under S7-1200

how to recover from an intermittent TCP timeout exception

What is the proper way to recover from a snap7 exception ISO : An error occurred during recv TCP : Connection timed out?

If I place a db_read() into a try/except clause to keep the application from aborting on TCP timeout, subsequent db_read() become out of sync. It seems somewhere the calls are queued. Probably in the native snap7 thread.

For example: If I have three locations I am reading from a PLC
3,260,4 contains value 100
3,272,4 contains value 200
1,104,4 contains value 300

-the first db_read(3,260,4) call successfully returns a value 100
-second db_read(3,272,4) call times out with TCP timeout exception
-third db_read(1,104,4) call will return value 200 (Not 300 like you would expect)
..
-a fourth call of db_read(3,260,4) will return the value from the third call above (300)

It seems the method calls get spooled into a queue and for every call that times out, the data returned will be delayed that many calls in the future.

Is there a way to throw away the buffer on a tcp timeout? Or is there some other philosophical approach I should be taking? It seems very dangerous to call a function with specific arguments and get the wrong data back. Thanks for any suggestions.

Fix travis OSX build

Travis has enabled the OSX support for this repository, but that is not (yet) compatible with the python mode we have been using. We need to wait for travis to fix this, or set up our own Python environment in the case of OSX.

can't find snap7 library. If installed, try running ldconfig

hi everyone
i installed snap7 in virtualenv in ubuntu desktop by using pip installation
but when i run my program i get this error:
snap7.snap7exceptions.Snap7Exception: can't find snap7 library. If installed, try running ldconfig

i add snap7 package in os.path array:

`import argparse
import ConfigParser
import sys
import re
import os

sys.path.append('/home/mostafa/plc/local/lib/python2.7/site-packages/')
sys.path.append('/home/mostafa/plc/lib/python2.7/site-packages/')

from snap7 import client

parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group()
group1 = parser.add_mutually_exclusive_group()
config = ConfigParser.ConfigParser()
group1.add_argument("-r", help="read from config file", action="store_true", )
group1.add_argument("-s", "--specify", help='specify PLC IP address. example:"ip,port,slot"')
group.add_argument("-S", "--stop", help="stop PLC.", action="store_true")`

by the way i use pycharm IDE
thank u

can't find library on python3 windows 8.1

Hi,

i am new on github, so please be gentle if i am at the wrong place for my question.

i try to install snap7 (to read from a S7-1200) with it's python-snap7 0.4 wrapper but i get always a traceback with the following simple code.

from time import sleep
import snap7
from snap7.util import *
import struct

plc = snap7.client.Client()

Traceback:

    Traceback (most recent call last):
    File "Y:\Lonnox\Projekte\Bibliothek\Python und SPS\S7-1200 Test.py", line 6, in <module>
    plc = snap7.client.Client()
    File "C:\Python34\lib\site-packages\snap7\client.py", line 30, in __init__
    self.library = load_library()
    File "C:\Python34\lib\site-packages\snap7\common.py", line 54, in load_library
    return Snap7Library(lib_location).cdll
    File "C:\Python34\lib\site-packages\snap7\common.py", line 46, in __init__
    raise Snap7Exception(msg)
    snap7.snap7exceptions.Snap7Exception: can't find snap7 library. If installed, try running ldconfig

idconfig is only available on Linux, right ?
The steps i do to install snap7 and python wrapper are:

  • Download snap7 from sourceforge and copy snap7.dll and snap7.lib to system32 folder of windows 8.1
  • Install wrapper by using pip install python-snap7 with no errors.
    How to install snap7 on windows correctly ?

i am using and familar with python3 / 32bit and can edit the source to work with python3, but i need a starting point how to set and load the needed library.

value error

when i try to run "snap7-server.py" or "client.py" or others i recieve the following error :

ValueError: Procedure called with not enough arguments (12 bytes missing) or wrong calling convention

i recieved this error on "Win Xp Sp3 32 bit" and "Python 2.76"

i tried on "Windows 7 Prof 64 bit" and "Python 2.76" code worked fine .

any help to work on XP ?

Read/Write Real values

Hi,

Im running python-snap7 on a raspberry communicating with a siemens S7. This is a project controlling our home brewery. I'm trying to use python-snap7 as a web-based HMI for the brewing process. Currently i have it working reading/writing to DB's without any problems. I quiet new to Python (Worked with several other languages though).

Most of my values are REAL and i have tried to convert the byte array into float but i have a missmatch between the S7 reading and the HMI. Seems like the S7 have a special treatment to convert 4bytes in to a REAL.

Do you have an example of how to operate with REAL values?

BTW: this is a superb repository!

BRGRDS

Uncaught Exception client.connect()

Hi,

when ever i try connect to an ip that is not available the Program is throwing an exception.

b' TCP : Unreachable peer'

i even tried to catch all exceptions with try: except:
But I can't figure out how to catch that particular exception
I'm new to python and just writing my first big application with it.

in the standard snap7 library i can read the result value. But in the python version there is the error_wrap function that is called. That raises the error. How do i catch it ? I need the possibility to catch that error, because the application should be running as a daemon.

here is a little example:

@classmethod
def workWithConnection(self):
    client = snap7.client.Client()
    try:
        client.connect(self.Ip, self.Rack, self.Slot) 
    except snap7.snap7exceptions.Snap7Exception as e:
        print(e)
        return 1  # <<<<<<That exception is caught and printed. But the same exception is thrown again. 
    except: 
        print("Some Other Error")
        return 1

    while(True):
        client.read_multi_vars(self.Data_Items)
        self.analyzeData()
        time.sleep(1)

    client.disconnect()
    client.destroy()
    return 0

Partner is not connecting

Nice to see you.
And I'm very appriciate for your awsome Snap7 Projects.
I am getting very much of help from your documentation.
Now I sucessfully send and recieve datas form plc via your
rich examples.(partenr)
So, It's means My PLC setting is correct.
but I couldnt success partner data send and recieve with
my python code.

(python 3.4 64bit , windows 7 64bit , Visual studio 2013)

from snap7 import partner
def h2d(num): # convert hex string to integer
return int(num,16)
ptn = partner.Partner()
ptn_stat = ptn.create(1)
print(ptn_stat)
ptn.start_to("192.29.31.253","192.29.31.254",h2d("0300"),h2d("1004"))
print ( ptn.get_status() )

I expacted returns "3" but, "1" is comming.
My Local IP is :192.29.31.253 , TSAP = 03.00
and My PLC IP is: 192.29.31.254 TSAP = 10.04
So I convert TSAP to inteager. for example
0x0300 is 768 , and 0x1004 is 4100.
and I was wating status 3 from PLCb but still 1.
I read your reference doccumentation but, I couldnt find
mention about python code.
So I ask to you courteously to let me know how send and recieve
data with python code please.
Any tiny help for me will be very huge help for me.
Im very poor in English. Please understand my poor expression.
Thanks.
Best Regards Jay.

Update to match snap 1.1.0 API

currently we made python-snap7 for 1.0.0.

changes:

From the wrappers point of view there were added 3 function in the client and 1 in the server.

Cli_SetConnectionParams
Cli_SetConnectionType
Cli_GetConnected

Server
Srv_SetReadEventsCallback (has the same params of Srv_SetEventsCallback, only a copy and paste is needed Emoji)

read_area reading merkers from PLC

Hello,
i want to read merker data from an PLC using client.read_area
i want to read MW0
this is the line i used but its not working, do i have to define the S7AreaMK ?
data = client.read_area(S7AreaMK,0, 0, 2)

File "./example.py", line 80, in Sequence
test_MB_read()
File "./example.py", line 48, in test_MB_read
data = client.read_area(S7AreaMK,db , start, size)
NameError: global name 'S7AreaMK' is not defined

i am very new to python, as a PLC programmer i have little experience in the object oriented languages.

Gr. Rick

test_client.py fail

I am new to python, github and all this stuff but used to work with PLC S7. I am using win7 64 bit, and running a virtual win xp as my virtual PLC. I have install snap7.dll and snap7 in "Windows/system32/ "folder and i think from "snap7.dll" to my virtual PLC is connected. I have test using clientdemo.exe file in his "rich demo folder" and it works.

Now I want to test with Python34 (I have find somewhere in the web that python-snap7 work with this version). What I have done is:

  1. install with "pip install python-snap7"
  2. open text_client.py, edit ip, rack and slot then run

I get the below error, please advice

E.

ERROR: setUpClass (main.TestClient)

Traceback (most recent call last):
File "C:\Temp\python-snap7-0.5\python-snap7-0.5\test\test_client.py", line 30, in setUpClass
cls.server_pid = Popen([server_path]).pid
File "C:\Python34\lib\subprocess.py", line 859, in init
restore_signals, start_new_session)
File "C:\Python34\lib\subprocess.py", line 1112, in _execute_child
startupinfo)
FileNotFoundError: [WinError 2] The system cannot find the file specified


Ran 1 test in 0.011s

FAILED (errors=1)

db_read and read_area return type

The db_read and read_area functions use a fixed return type which is a sequence of c_int8. This is done via the wordlen_to_ctypes map.

wordlen_to_ctypes = ADict({
    S7WLBit: ctypes.c_int16,
    S7WLByte: ctypes.c_int8,
    S7WLWord: ctypes.c_int16,
    S7WLDWord: ctypes.c_int32,
    S7WLReal: ctypes.c_int32,
    S7WLCounter: ctypes.c_int16,
    S7WLTimer: ctypes.c_int16,
})

And then in the function

wordlen = snap7.snap7types.S7WLByte
type_ = snap7.snap7types.wordlen_to_ctypes[wordlen]
data = (type_ * size)()
result = self.library.Cli_ReadArea(self.pointer, area, dbnumber, start, size, wordlen, byref(data))

data is passed by reference to the library to be populated with data from the PLC

The size parameter is then used to determine how many c_int8 units to read.

It might be better to use c_uint8 as the data type so that a sequence of bytes is returned instead of signed integers. I think that the two functions are basically reading a series of bytes from a specific area starting at a given offset so returning something that is analogous to bytes instead of signed integers seems to better match the purpose.

I am not sure if the right thing to do is to modify each function that should return a sequence of bytes or to modify the wordlen_to_ctypes map so that S7WLByte points to c_uint8. Also would it then make sense that S7WLWord and S7WLDWord be changed to point at unsigned types? I haven't read through much of the library so I don't know what all of the use cases for wordlen_to_ctypes are.

Also it appears that in the Snap7 library that WordLen is not the actual word length but used an indicator of the S7 Data Type that is being read or written.

Here is an example from the Snap7 library where it converts to a WordLen value to a the size in bytes for that data type

found in s7_micro_client.cpp

switch (WordLength){
    case S7WLBit     : return 1;  // S7 sends 1 byte per bit
    case S7WLByte    : return 1;
    case S7WLChar    : return 1;
    case S7WLWord    : return 2;
    case S7WLDWord   : return 4;
    case S7WLInt     : return 2;
    case S7WLDInt    : return 4;
    case S7WLReal    : return 4;
    case S7WLCounter : return 2;
    case S7WLTimer   : return 2;
    default          : return 0;
}

Here is a modified version of read_area I have been using test against a S7-319 CPU reading REALs and INTs.

def read_area(self, area, dbnumber, start, size):
    """This is the main function to read data from a PLC.
    With it you can read DB, Inputs, Outputs, Merkers, Timers and Counters.

    :param dbnumber: The DB number, only used when area= S7AreaDB
    :param start: offset to start reading
    :param size: number of bytes to read
    """
    assert area in snap7.snap7types.areas.values()
    wordlen = snap7.snap7types.S7WLByte
    logging.debug("reading area: %s dbnumber: %s start: %s: amount %s: "
                  "wordlen: %s" % (area, dbnumber, start, size, wordlen))
    data = (c_uint8 * size)()
    result = self.library.Cli_ReadArea(self.pointer, area, dbnumber, start,
                                       size, wordlen, byref(data))
    check_error(result, context="client")
    return data

and here is how I am using it

result = client.read_area(S7AreaDB, 200, 16, 4)
bytes = ''.join([chr(x) for x in result])
real_num = struct.unpack('>f', bytes)
print(real_num)

result = client.read_area(S7AreaDB, 200, 2, 2)
bytes = ''.join([chr(x) for x in result])
int_num = struct.unpack('>h', bytes)
print(int_num)

Download

I am trying to upload OB 1 from the PLC and then downloading the same code to the same PLC (also OB 1). Unfortunately it is not working or I did not understand the full upload and download functions:

#Uploading code from PLC
poe_block = self.client.full_upload("OB", 1)
block_size = poe_block[1]
total_code = poe_block[0][:block_size]

#now the same code is downloaded again
self.client.download(data=total_code, block_num=1)

My console output:

INFO:snap7.client:creating snap7 client
INFO:snap7.client:connecting to 192.168.200.199:102 rack 0 slot 0
DEBUG:snap7.client:setting param number 2 to 102
DEBUG:snap7.common:error text for 0x1b00000
ERROR:snap7.common:CPU : block insert refused
Traceback (most recent call last):
  File "/Users/mateusz/ics_payload_generator/fusabot/test.py", line 12, in 
    print attacker.upload_mc7_code('/Users/mateusz/ics_payload_generator/showcase/current3.mc7', 1)
  File "/Users/mateusz/ics_payload_generator/fusabot/attacks/attacker.py", line 76, in upload_mc7_code
    return self.client.download(data=mc7_block, block_num=block_number)
  File "/usr/local/Cellar/python/2.7.8/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/snap7/client.py", line 21, in f
    check_error(code, context="client")
  File "/usr/local/Cellar/python/2.7.8/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/snap7/common.py", line 65, in check_error
    raise Snap7Exception(error)
snap7.snap7exceptions.Snap7Exception: CPU : block insert refused

Show the Snap7 code for beginners...

I'm a programmer for Step7. I don't know Phyton, C# or other high level languages very well. I tried to create a small pyton program to read some variables from a CPU317 from siemens, but i failed to adopt the sample code which is provided on your website.

I have dream...

Could anyone use my sample PLC program to create a phyton snap7 program to display some of the variables i created in the DB1 and the I/O area 1-10 ?

Here you could download my program :

https://www.magentacloud.de/share/kpnb0inqu8

Thank you very much...

Phone: 0049 6151 32 1551
Email: [email protected]

Keep automatically searching for connection

Hi,

I have downloaded and installed snap7 but sometimes I get this error:
(
No handles could be found for logger "snap7.common"

Traceback (most recent call last):
File "/home/pi/Desktop/raspberry/TestDI.py", line 31, in
client.connect('192.168.5.2', 0, 1)
File "/usr/local/lib/python2.7/dist-packages/snap7/client.py", line 25, in f
check_error(code, context="client")
File "/usr/local/lib/python2.7/dist-packages/snap7/common.py", line 65, in check_error
raise Snap7Exception(error)
Snap7Exception: TCP : Unreachable peer_
)

I know this is because I don't have connection with my PLC yet, because if I run the program again I have connection and I can send values to my PLC.
But I want to automatically start my program (that code works, I tried it with an other program). But I don't have connection with internet yet if I'm starting up my Raspberry.
Is there a solution by putting some kind of loop somewhere in your code so it keeps searching for wifi instead of immediately giving an error?
I'm a real beginner and I have no clue where to start.
Thanking you in advance.

util.get_int() broken on Linux / Python 2.7.3

When sending a Logo8 counter-value via network-analog-output to a snap7-server
the values returned from util.get_int() were not always correct.
The problem is also reproducible with util.set_int() and util.get_int() :

import snap7
server = snap7.server.Server(log=True)
DB1 = (snap7.snap7types.wordlen_to_ctypes[snap7.snap7types.S7WLByte]*4)()
server.register_area(snap7.snap7types.srvAreaDB, 1, DB1)
for Data_Set in (-32768, -16385, -256, -128, -127, 0, 127, 128, 255, 256, 16384, 32767):
    snap7.util.set_int(DB1, 0, Data_Set)
    Data_Get = snap7.util.get_int(DB1, 0)
    print "%6d %6d %s" % (Data_Set, Data_Get, (Data_Set==Data_Get))

Output:

 -32768 -32768 True
 -16385 -16641 False
   -256   -256 True
   -128   -384 False
   -127   -383 False
      0      0 True
    127    127 True
    128   -128 False
    255     -1 False
    256    256 True
  16384  16384 True
  32767  32511 False

The problem is due to python sign handling of integers.
A working fix in util.get_int():

...
    byte1 = _bytearray[byte_index + 1] & 0xFF

Output:

-32768 -32768 True
-16385 -16385 True
  -256   -256 True
  -128   -128 True
  -127   -127 True
     0      0 True
   127    127 True
   128    128 True
   255    255 True
   256    256 True
 16384  16384 True
 32767  32767 True

byte0 is left with sign, because Logo int ranges from -32768 ... +32767

Writing only bit

Hi everybody,

I'm sort of a neewb in programming but I made nice script in python for connecting to plc and doing somethin... anyway, I made it working for INT and CHAR but BIT is a little problem... like I would like to change DB DBB 2.1 from 0 to 1 without reading the whole byte and then parsing it, adding, summing and sending back :( is there any other way?

Thanks for answer!
Tom

set_string not working correctly

I try to use set_string in a byte array, but only the first 2 characters are written correctly, the rest is garbled. For example, when I use: set_string(db10, 0, 'abcd')
and I read it back with get_string, I get: 'ab@I'
Also, the docstring mentions a size argument that is not present..

S7WLByte in snap7types.py has incorrect value

The value of the variable S7WLByte is 0x01, I believe that it should be 0x02 from reading the Snap7 documentation and source code.

When the value is set to 0x01 the following call:
client.read_area(S7AreaDB, 200, 16, 4)

causes an exception:
snap7.snap7exceptions.Snap7Exception: CPU : Invalid Transport size

when S7WLByte is set to 0x02 the call results in data being returned.

S7-200/Logo PLCs Can't Connect

Cannot connect to my S7-200 PLC using the following code:

import snap7
plc = snap7.client.Client()
plc.set_connection_params("10.0.0.250",10,10)
plc.connect("10.0.0.250",0,1)

In the Client class the connect function uses the library.ConnectTo(...). Which is not going to work for logos or the 200 series. There needs to be a library.Cli_Connect().

I was able to connect to the S7-200 using C# the following code :
//S7-200 example
Snap7.S7Client plc = new Snap7.S7Client();
plc.SetConnectionParams("10.10.55.250", 0x1100, 0x1100);
Snap7.S7Client.S7CpuInfo info = new S7Client.S7CpuInfo();
plc.Connect();
Console.Write("Connected:{0}",plc.Connected());
Console.ReadLine();
plc.Disconnect();
//S7-1200 example
Snap7.S7Client plc1200 = new Snap7.S7Client();
//no connection params
plc1200.ConnectTo("10.0.0.251",0,1);
Console.Write("Connected:{0}", plc1200.Connected());
Console.ReadLine();
plc1200.Disconnect();

I tried getting connected to the S7-200 using this:\

plc.library.Cli_SetConnectionParams(plc.pointer,c_char_p(six.b("10.0.0.250")),c_uint16(10),c_uint16(10))
plc.library.Cli_Connect()

But i get a segmentation fault. :-(.
any help would be appreciated. If u need to borrow a test plc let me know.

Server crash on Windows with 32 bit python

INFO:snap7.server:creating server
INFO:snap7.server:setting event callback
INFO:snap7.server:registering area 5, index 1, size 100
INFO:root:setting server TCP port to 1102
INFO:snap7.server:starting server on 0.0.0.0:1102
INFO:snap7.server:callback event: 2014-07-27 15:11:01 Server started
INFO:snap7.server:callback event: 2014-07-27 15:11:01 Server started
Traceback (most recent call last):
  File "C:/Users/Gijs/Documents/GitHub/python-snap7/snap7/bin/snap7-server.py", line 36, in <module>
    mainloop()
  File "C:/Users/Gijs/Documents/GitHub/python-snap7/snap7/bin/snap7-server.py", line 18, in mainloop
    server.start(tcpport=tcpport)
  File "C:\Users\Gijs\Documents\GitHub\python-snap7\snap7\server.py", line 17, in f
    code = func(*args, **kw)
  File "C:\Users\Gijs\Documents\GitHub\python-snap7\snap7\server.py", line 150, in start
    return self.library.Srv_Start(self.snap7server)
WindowsError: exception: access violation writing 0x0000001A

Add Python2.6 support?

@oldfellow reported:
"""
Because I'm running python 2.6 I need to modify the util.py, because in python 2.6 the Collections doesn't provide OrderedDict.
I have installed ordereddict with pip and modified line 11 in util.py:

from Collections import OrderedDict
import ordereddict

Maybe this creates the issue. But I don't know how to solve, because I can't change to python 2.7.

"""
If this is the only python2.6 compatibility then maybe it is a good idea to add Python2.6 support. But probably not, since it makes it harder to have a mixed python2/python3 code base.

Update to support 64bit snap7 1.2.0 API

Not sure about the changes, just tried to run it and got a segfault:

INFO:snap7.server:creating server
INFO:snap7.server:setting event callback
Segmentation fault: 11

trace:

stop reason = EXC_BAD_ACCESS (code=1, address=0x88fc40)
frame #0: 0x0000000100643d74 libsnap7.so`TCustomMsgServer::SetEventsCallBack(void (*)(void*, TSrvEvent*, int), void*) + 4
frame #1: 0x00000001004d26e7 _ctypes.so`ffi_call_unix64 + 79
...

Problem running in Windows 32bit

Currently i 'm testing with the python-snap7 software for creating a database connector to s7 plc.

But i have an issue with windows 7 32 bits version. The next exception appears:

File "......", line 437, in set_param
byref(type_(value)))
ValueError: Procedure called with not enough arguments (12 bytes missing) or wrong calling convention

In windows 7 64 bit it works fine.

Client problem

We get this error from Python and don't know how to solve it.
We want to use the Python to write values in a DB(109). They are real.
We have no experience with the raspberry, so could you help us please?

Traceback (most recent call last):
File "/home/pi/testcom2.py", line 17, in
client = snap7.client.Client()
File "/usr/local/lib/python2.7/dist-packages/snap7/client.py", line 36, in init
self.create()
File "/usr/local/lib/python2.7/dist-packages/snap7/client.py", line 43, in create
self.library.Cli_Create.restype = c_void_p
AttributeError: 'NoneType' object has no attribute 'Cli_Create'

This is our programme:

import re
from ctypes import c_int, c_char_p, byref, sizeof, c_uint16, c_int32, c_byte
from ctypes import c_void_p

import logging

import snap7
from snap7 import six
from snap7.snap7types import S7Object, buffer_type, buffer_size, BlocksList
from snap7.snap7types import TS7BlockInfo, param_types, cpu_statuses

from snap7.common import check_error, load_library, ipv4
from snap7.snap7exceptions import Snap7Exception

logger = logging.getLogger(name)

client = snap7.client.Client()
client.connect('192.168.5.2', 0, 1)

class Client(object):
def db_write(self,db_number , start, data):
"""
Writes to a DB object.

    :param start: write offset
    :param data: bytearray
    """
    db_number = 109
    start = 0
    data = ff
    

    
    wordlen = snap7.snap7types.S7WLReal
    type_ = snap7.snap7types.wordlen_to_ctypes[wordlen]
    size = len(data)
    cdata = (type_ * size).from_buffer(data)
    logger.debug("db_write db_number:%s start:%s size:%s data:%s" %
                 (db_number, start, size, data))
    return self.library.Cli_DBWrite(self.pointer, db_number, start, size,
                                    byref(cdata))

Issue in "list_blocks_of_type code"

I was trying to get the "list_blocks_of_type" code working but every time I called it, I was returned a 10 Integer Array containing some rather large numbers. After doing some debugging I deduced that if I took the large number in each array element and split it into 2 * 16 bit words then the array contained some of the block numbers of that block type. I had previously authored some C++ code that used the Snap7 library and had this running so looked at my previous code and noticed that I was passing in (by reference) a TS7BlocksOfType structure which actually equated to a integer array that is 0x2000 in size. I changed the line in client.py for the function "def list_blocks_of_type(self, blocktype, size):" that was

data = (c_int * 10)() to be data = (c_uint16 * 0x2000)()

I am now return an array of integers containing all of the data (and then some as the array is 0x2000 whether it is used or not). Perhaps the proper way to handle this is to use the "size" variable in the declaration of the data array

ie data = (c_uint16 * size)()

Then an array of integers the exact size required is returned.

Reading Single Input or Output

Hello,

I am really not very good at PLC also Python ๐Ÿ˜„
I am working on python-snap7 on a few days. I am able to connect, read data and convert to boolean but I can not understand which one is the boolean that I am looking for.
In brief, how can I read a specific input or output from PLC? (e.g. : I3.2 or Q0.4 etc.)
I will be glad if you explain or share some links. Because I couldn't find any.

Thanks,
Ufuk.

LOGO connectivity

Hello, I am having problems connecting to a LOGO 0BA7 with python-snap7. With the script below I receive a handle but can not get any further.

I have tried this with Windows7 and Ubuntu and receive the same result. I tried the Windows7 snap7 GUI and it works and I am able to connect and read data.

Here is my code:

client = snap7.client.Client()
print repr(client)
x = client.set_connection_params("192.168.99.191", 0x0300, 0x0200)
print repr(x)
y = client.get_connected()
print repr(y)"

and the result:

<snap7.client.Client object at 0x266ab90> handle
None
False

ISO : An error occurred during recv TCP : Connection timed out' - PLC LOGO8

I encountered a strange error with python-snap7. I tested it on two diffrent windows and a linux pc and one work and the other 2 doesn't. Setup exactly the same on the windows pc's.

Working PC:

PC Info:

working_correct_pcinfo

Python snap7 working correct and set ouput value:

working_correct

Error PC:

PC Info

error_pcinfo

Python snap7 error:

INFO:snap7.client:creating snap7 client
INFO:snap7.client:connecting to 10.0.0.220:102 rack 0 slot 2
DEBUG:snap7.client:setting param number 2 to 102
DEBUG:snap7.common:error text for 0xa274c
ERROR:snap7.common:b' ISO : An error occurred during recv TCP : Connection timed out'
Traceback (most recent call last):
File "C:\Snap7\python-snap7\test\lottie.py", line 125, in
plc = LOGO8('10.0.0.220',debug=True)
File "C:\Snap7\python-snap7\test\lottie.py", line 29, in init
self.plc.connect(ip,0,2)
File "C:\Python34\lib\site-packages\snap7\client.py", line 25, in f
check_error(code, context="client")
File "C:\Python34\lib\site-packages\snap7\common.py", line 65, in check_error
raise Snap7Exception(error)
snap7.snap7exceptions.Snap7Exception: b' ISO : An error occurred during recv TCP : Connection timed out'

error

Ping PLC LOGO8 working correct, can also connect via telnet 10.0.0.220:102

pingplc

telnet

I recieved the same error on linux opensuse 42.1 with python snap7

Can anyone help regarding this error - there must be something I missed because why will one connect and the other one doesn't

Read Input from Siemens LOGO! 8

Hi Everybody

I've been trying to read ou the state of the digital inputs of my LOGO 8 module but it didn't work...
Has anybody an idea which value I have to put for the "area" ?

For example I want to read out the input byte for the inputs I0 to I7 (VM range 1024.0 - 1024.7):

import snap7
plc = snap7.client.Client()
plc.set_connection_params('192.168.0.5',0x0300,0x0200)
plc.connect('192.168.0.5',0,1)
plc.get_connected()
True
byte = plc.read_area(DB1.X1024, 0, 0, 1)
Traceback (most recent call last):
File "<pyshell#5>", line 1, in
byte = plc.read_area(DB1.X1024, 0, 0, 1)
NameError: name 'DB1' is not defined

I would appreciate any help! Thanks.
Best regards
Lorenz

Problems getting python-snap7 to work on S7-1200

Hi,

I installed snap7 and python-snap7 on a raspberry pi3, but I cant get it to work.

I can ping the plc with the pi.

But when I run the example code "boolean.py", I get the following output:

No handlers could be found for logger "snap7.common"
Traceback (most recent call last):
File "test4.py", line 21, in
reading = plc.db_read(31, 120, 1) # read 1 byte from db 31 staring from byte 120
File "/usr/local/lib/python2.7/dist-packages/snap7/client.py", line 142, in db_read
check_error(result, context="client")
File "/usr/local/lib/python2.7/dist-packages/snap7/common.py", line 65, in check_error
raise Snap7Exception(error)
snap7.snap7exceptions.Snap7Exception: CLI : function refused by CPU (Unknown error)

I'm a reasonably skilled PLC programmer, but just a beginner at the Raspberry and Pyhon, please help.

Thanks,

Paul

snap7 module not found windows 10

Hello

I am a new to python (and to GitHub) and am trying it out for an automation project of mine.
I am trying to use 64-bit Python 3.5.3 with 64 bit Snap7 on Windows 10 (also 64 bit).
I have copied the .dll and .lib files of snap7 and added it to system32 folder of windows.
I have also copied it to my python path.
But, when I import snap7 , it says 'Importerror: no module named snap7'
Does python-snap7 work in Windows 10? The document said it 'may' work on other OS.
Pardon me if this is trivial. It would be very helpful if I can get some guidance.

Thank you.

Snap 7 server: python

How to use the server function? There isn't any documentation on how to do this.
I've created a server object plc and I'm trying to create a register area for DB50.

Different behavior of read_area on windows and linux. read_area throws ValueError

Hi,
Environment:
OS (Linux and Windows 7 ) : 64bit.
snap7-full-1.3.0.tar.gz
python-snap7-0.4.tar.gz

I have different behavior executing the same query on windows and linux.
I want to read 6 Objects from DB2
read_area(132, 2, 0, 6)

The result on Windows is fine:
00 AB CD 11 B9 01 # This matches to the data in the plc.

On Linux I get the error:
File "/usr/local/lib/python2.6/site-packages/snap7/client.py", line 210, in read_area
return bytearray(data)
ValueError: byte must be in range(0, 256)

For debugging I add the following line in front of the return in line 210:
print "".join("%02x " % b for b in data)

This gives me the Information that on linux the bytestream looks like this:
00 -55 -33 11 -47 01
And "-55" of course throws the ValueError.

When I run the same query with snap7 ( cpp or plain-c ), I get the correct values on windows and linux. Therefore I guess the issue must be somewhere in the python interface.

Any idea how to solve this issue?

Because I'm running python 2.6 I need to modify the util.py, because in python 2.6 the Collections doesn't provide OrderedDict.
I have installed ordereddict with pip and modified line 11 in util.py:

from Collections import OrderedDict

import ordereddict
Maybe this creates the issue. But I don't know how to solve, because I can't change to python 2.7.

Thanks in advance.

Reading from PLC | db_read ArgumentError

Dear Snap7 developers and users,

I have a problem with the "db_read(db_number, start, size)" function. The exact problem is with the "start" variable, to which I have to give the start address
of the variable inside the plc which I wish to read. If I set an integer value of this var the program runs without issues, however I do have some variables
inside the PLC with offsets like 4.1, 8.4 etc. So they are not integer values. When I set these offsets as "start" the function doesn't work and stops with the following error:

terminal

Here is a part of my program I use to read from the PLC:

code

Is there any way to set non-rounded "Start" values?

I develop the program under ubuntu in python language.

Thank you for the snap7 project
Also thank you in advance for the helps and tips!

LOGO connectivity - continued

Hi Guys,

Mind if I ask for this issue to be re-opened. I have an 0BA7 sitting on my desk ready to do some debugging as required.

I have snap7-1.2.1 and installed python-snap7 via pip (0.2.2).

Test code:

import logging
import snap7

logging.basicConfig(level=logging.DEBUG)

c = snap7.client.Client()
c.set_connection_params('10.205.0.251', 0x0300, 0x0200)
c.connect("10.205.0.251", 0, 1)

Output

INFO:snap7.client:creating snap7 client
INFO:snap7.client:connecting to 10.205.0.251:102 rack 0 slot 1
DEBUG:snap7.client:setting param number 2 to 102
DEBUG:snap7.common:error text for 0xa003c
ERROR:snap7.common: ISO : An error occurred during recv TCP : Connection timed out

I've played around with the Snap7 Client Demo and everything works ok. (Can only use TSAP mode as the docs say)

Any suggestions?

Apologies my experience with the Siemens line of PLCs is not great, but learning as I write this.

Reading DINT

Hi Again,

i am triyng to read DINT data fom a DATABLOCK.

simply i have the following code :
"snap7.util.get_dword(self.client.db_read(100,106, 4), 0)"

and i recieve :
13595157 instead of 1405647.

i tried to pla bytes a little bit but i stacked when i see
(bytearray(b'\x00\x15r\xcf'), 0), because the "\x15r" is 2 bytes and i don't know what does "r" mean.

Problem with Test suite

Hello,

I have problems with the test suite.

The command
sudo python /test/test_partner.py

runs without errors. :-)

Then I do:
sudo python test/test_server.py

....ERROR:snap7.common:LIB : Invalid param supplied
.ERROR:snap7.common:CPU : total data exceeds the PDU size
........ERROR:snap7.common:SRV : Cannot change this param now
..ERROR:snap7.common:SRV : Invalid param(s) supplied

..

Ran 17 tests in 2.135s

OK

I work on ubuntu 13.10

Have you a idea where the problem is?

Reading timers and counters

Hi there,
I got to write and read DB, MK, PE, PA using a siemens plc. It works with booleans, byte, words, reals and dwords.
Now I can't get to read a timer, using the same read_area function.
result=plc.read_area(areas["TM"],0,13,STWLTimer)
where 13 is the timer I want to read. In the plc program is S_EVERZ 13

It always says "CPU: address out of range".

Where am I wrong ?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.