Welcome to python-snap7’s documentation!¶
Contents:
Introduction¶
python-snap7 is a Python wrapper for the Snap7 library. Snap7 i san open source, 32/64 bit, multi-platform Ethernet communication suite for interfacing natively with Siemens S7 PLCs.
Python-snap7 is developer for snap7 1.1.0 and Python2.7. It is tested on Windows (8.1 64 bit) and Linux, but it may work on other operating systems. Python 2.6 and Python 3+ may work, but are not fully tested yet.
The project development is centralized on github.
Installation¶
here you can find out how to install python-snap7 on your system.
Snap7¶
To use python-snap7 you need to have the snap7 library installed.
Ubuntu¶
If you are using Ubuntu you can use the Ubuntu packages from our launchpad PPA. To install:
$ sudo add-apt-repository ppa:gijzelaar/snap7
$ sudo apt-get update
$ sudo apt-get install libsnap71 libsnap7-dev
Windows¶
Download the zip file from the sourceforce page. Unzip the zip file, and copy* releaseWindows<Win64/Win32>snap7.dll* somewhere in you system PATH, for example C:WINDOWSsystem32. Alternatively you can copy the file somewhere on your file system and adjust the system PATH.
Compile from source¶
If you are not using Ubuntu or if you want to have more control you can download the latest source from the sourceforce page and do a manual compile. Download the file and run:
$ p7zip -d snap7-full-1.0.0.7z # requires the p7 program
$ cd build/<platform> # where platform is unix or windows
$ make -f <arch>.mk # where arch is your architecture, for example x86_64_linux
For more information about or help with compilation please check out the documentation on the snap7 website.
development¶
Github¶
We develop python-snap7 on github. If you have any problems with python-snap7 please raise an issue in the issue tracker. Even better is if you have a solution to problem! In that case you can make our live easier by following these steps:
- fork our repository on github
- Add a tests that will fail because of the problem
- Fix the problem
- Run the test suite again
- Commit to your repository
- Issue a github pullrequest.
Also we try to be as much pep8 compatible as possible, where possible and reasonable.
Test suite¶
python-snap7 comes with a test suite with 100% coverage. This test suite verifies that the code actually works and makes development much easier. To run all tests please run from the source:
$ ./run_tests.sh
Note that some tests require to run as root, since snap7 needs to bind on a privileged TCP port.
If the test complain about missing Python modules make sure the source directory is in your PYTHONPATH environment variable, or the python-snap7 module is installed.
Credits¶
python-snap7 is created by Gijs Molenaar and Stephan Preeker.
Special thanks to go to Davide Nardella for creating snap7, Thomas Hergenhahn for his libnodave and Thomas W for his S7comm wireshark plugin.
Client¶
Snap7 client used for connection to a siemens7 server.
-
class
snap7.client.
Client
[source]¶ A snap7 client
-
ab_read
(start, size)[source]¶ This is a lean function of Cli_ReadArea() to read PLC process outputs.
-
ab_write
(start, data)[source]¶ This is a lean function of Cli_WriteArea() to write PLC process outputs
-
as_db_read
(db_number, start, size)[source]¶ This is the asynchronous counterpart of Cli_DBRead.
Returns: user buffer.
-
db_read
(db_number, start, size)[source]¶ This is a lean function of Cli_ReadArea() to read PLC DB.
Returns: user buffer.
-
full_upload
(_type, block_num)[source]¶ Uploads a full block body from AG. The whole block (including header and footer) is copied into the user buffer.
Parameters: block_num – Number of Block
-
get_block_info
(blocktype, db_number)[source]¶ Returns the block information for the specified block.
-
get_connected
()[source]¶ Returns the connection status
Returns: a boolean that indicates if connected.
-
list_blocks
()[source]¶ Returns the AG blocks amount divided by type.
Returns: a snap7.types.BlocksList object.
-
list_blocks_of_type
(blocktype, size)[source]¶ This function returns the AG list of a specified block type.
-
read_area
(area, dbnumber, start, size)[source]¶ This is the main function to read data from a PLC. With it you can read DB, Inputs, Outputs, Merkers, Timers and Counters.
Parameters: - dbnumber – The DB number, only used when area= S7AreaDB
- start – offset to start writing
- size – number of units to read
-
read_multi_vars
(items)[source]¶ This function read multiple variables from the PLC.
Parameters: items – list of S7DataItem objects Returns: a tuple with the return code and a list of data items
-
set_connection_params
(address, local_tsap, remote_tsap)[source]¶ Sets internally (IP, LocalTSAP, RemoteTSAP) Coordinates. This function must be called just before Cli_Connect().
Parameters: - address – PLC/Equipment IPV4 Address, for example “192.168.1.12”
- local_tsap – Local TSAP (PC TSAP)
- remote_tsap – Remote TSAP (PLC TSAP)
-
Server¶
Snap7 server used for mimicking a siemens 7 server.
-
class
snap7.server.
Server
(log=True)[source]¶ A fake S7 server.
-
event_text
(event)[source]¶ Returns a textual explanation of a given event object
Parameters: event – an PSrvEvent struct object Returns: the error string
-
Partner¶
Snap7 code for partnering with a siemens 7 server.
This allows you to create a S7 peer to peer communication. Unlike the client-server model, where the client makes a request and the server replies to it, the peer to peer model sees two components with same rights, each of them can send data asynchronously. The only difference between them is the one who is requesting the connection.
-
class
snap7.partner.
Partner
(active=False)[source]¶ A snap7 partner.
-
as_b_send
()[source]¶ Sends a data packet to the partner. This function is asynchronous, i.e. it terminates immediately, a completion method is needed to know when the transfer is complete.
-
b_recv
()[source]¶ Receives a data packet from the partner. This function is synchronous, it waits until a packet is received or the timeout supplied expires.
-
b_send
()[source]¶ Sends a data packet to the partner. This function is synchronous, i.e. it terminates when the transfer job (send+ack) is complete.
-
check_as_b_send_completion
()[source]¶ Checks if the current asynchronous send job was completed and terminates immediately.
-
create
(active=False)[source]¶ Creates a Partner and returns its handle, which is the reference that you have to use every time you refer to that Partner.
Parameters: active – 0 Returns: a pointer to the partner object
-
destroy
()[source]¶ Destroy a Partner of given handle. Before destruction the Partner is stopped, all clients disconnected and all shared memory blocks released.
-
get_stats
()[source]¶ Returns some statistics.
Returns: a tuple containing bytes send, received, send errors, recv errors
-
set_recv_callback
()[source]¶ Sets the user callback that the Partner object has to call when a data packet is incoming.
-
Util¶
This module contains utility functions for working with PLC DB objects. There are functions to work with the raw bytearray data snap7 functions return In order to work with this data you need to make python able to work with the PLC bytearray data.
For example code see test_util.py and example.py in the example folder.
example:
spec/DB layout
# Byte index Variable name Datatype
layout="""
4 ID INT
6 NAME STRING[6]
12.0 testbool1 BOOL
12.1 testbool2 BOOL
12.2 testbool3 BOOL
12.3 testbool4 BOOL
12.4 testbool5 BOOL
12.5 testbool6 BOOL
12.6 testbool7 BOOL
12.7 testbool8 BOOL
13 testReal REAL
17 testDword DWORD
"""
client = snap7.client.Client()
client.connect('192.168.200.24', 0, 3)
# this looks confusing but this means uploading from the PLC to YOU
# so downloading in the PC world :)
all_data = client.upload(db_number)
simple:
db1 = snap7.util.DB(
db_number, # the db we use
all_data, # bytearray from the plc
layout, # layout specification DB variable data
# A DB specification is the specification of a
# DB object in the PLC you can find it using
# the dataview option on a DB object in PCS7
17+2, # size of the specification 17 is start
# of last value
# which is a DWORD which is 2 bytes,
1, # number of row's / specifications
id_field='ID', # field we can use to identify a row.
# default index is used
layout_offset=4, # sometimes specification does not start a 0
# like in our example
db_offset=0 # At which point in 'all_data' should we start
# reading. if could be that the specification
# does not start at 0
)
Now we can use db1 in python as a dict. if 'ID' contains
the 'test' we can identify the 'test' row in the all_data bytearray
To test of you layout matches the data from the plc you can
just print db1[0] or db['test'] in the example
db1['test']['testbool1'] = 0
If we do not specify a id_field this should work to read out the
same data.
db1[0]['testbool1']
to read and write a single Row from the plc. takes like 5ms!
db1['test'].write()
db1['test'].read()
-
class
snap7.util.
DB
(db_number, _bytearray, specification, row_size, size, id_field=None, db_offset=0, layout_offset=0, row_offset=0)[source]¶ Manage a DB bytearray block given a specification of the Layout.
It is possible to have many repetitive instances of a specification this is called a “row”.
probably most usecases there is just one row
db1[0][‘testbool1’] = test db1.write() # puts data in plc
-
class
snap7.util.
DB_Row
(_bytearray, _specification, row_size=0, db_offset=0, layout_offset=0, row_offset=0)[source]¶ Provide ROW API for DB bytearray
-
snap7.util.
get_bool
(_bytearray, byte_index, bool_index)[source]¶ Get the boolean value from location in bytearray
-
snap7.util.
get_int
(_bytearray, byte_index)[source]¶ Get int value from bytearray.
int are represented in two bytes
-
snap7.util.
parse_specification
(db_specification)[source]¶ Create a db specification derived from a dataview of a db in which the byte layout is specified
-
snap7.util.
set_bool
(_bytearray, byte_index, bool_index, value)[source]¶ Set boolean value on location in bytearray